Merge "use importance instead of score"
diff --git a/api/current.txt b/api/current.txt
index feb43da..8d174c3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -728,6 +728,7 @@
     field public static final int label = 16842753; // 0x1010001
     field public static final int labelFor = 16843718; // 0x10103c6
     field public static final int labelTextSize = 16843317; // 0x1010235
+    field public static final int languageTag = 16844041; // 0x1010509
     field public static final int largeHeap = 16843610; // 0x101035a
     field public static final int largeScreens = 16843398; // 0x1010286
     field public static final int largestWidthLimitDp = 16843622; // 0x1010366
@@ -5802,6 +5803,7 @@
     method public void lockNow();
     method public void removeActiveAdmin(android.content.ComponentName);
     method public boolean removeCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
+    method public boolean removeKeyPair(android.content.ComponentName, java.lang.String);
     method public boolean removeUser(android.content.ComponentName, android.os.UserHandle);
     method public boolean resetPassword(java.lang.String, int);
     method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean);
@@ -7779,6 +7781,7 @@
     method public abstract int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
     method public abstract deprecated void clearWallpaper() throws java.io.IOException;
     method public abstract android.content.Context createConfigurationContext(android.content.res.Configuration);
+    method public abstract android.content.Context createDeviceEncryptedStorageContext();
     method public abstract android.content.Context createDisplayContext(android.view.Display);
     method public abstract android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
     method public abstract java.lang.String[] databaseList();
@@ -7802,7 +7805,6 @@
     method public final android.content.res.ColorStateList getColorStateList(int);
     method public abstract android.content.ContentResolver getContentResolver();
     method public abstract java.io.File getDatabasePath(java.lang.String);
-    method public abstract java.io.File getDeviceEncryptedFilesDir();
     method public abstract java.io.File getDir(java.lang.String, int);
     method public final android.graphics.drawable.Drawable getDrawable(int);
     method public abstract java.io.File getExternalCacheDir();
@@ -7823,6 +7825,7 @@
     method public abstract android.content.res.Resources getResources();
     method public abstract android.content.SharedPreferences getSharedPreferences(java.lang.String, int);
     method public abstract android.content.SharedPreferences getSharedPreferences(java.io.File, int);
+    method public abstract java.io.File getSharedPreferencesPath(java.lang.String);
     method public final java.lang.String getString(int);
     method public final java.lang.String getString(int, java.lang.Object...);
     method public abstract java.lang.Object getSystemService(java.lang.String);
@@ -7834,6 +7837,7 @@
     method public abstract deprecated int getWallpaperDesiredMinimumHeight();
     method public abstract deprecated int getWallpaperDesiredMinimumWidth();
     method public abstract void grantUriPermission(java.lang.String, android.net.Uri, int);
+    method public abstract boolean isDeviceEncryptedStorage();
     method public boolean isRestricted();
     method public final android.content.res.TypedArray obtainStyledAttributes(int[]);
     method public final android.content.res.TypedArray obtainStyledAttributes(int, int[]) throws android.content.res.Resources.NotFoundException;
@@ -7965,6 +7969,7 @@
     method public int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
     method public deprecated void clearWallpaper() throws java.io.IOException;
     method public android.content.Context createConfigurationContext(android.content.res.Configuration);
+    method public android.content.Context createDeviceEncryptedStorageContext();
     method public android.content.Context createDisplayContext(android.view.Display);
     method public android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
     method public java.lang.String[] databaseList();
@@ -7987,7 +7992,6 @@
     method public java.io.File getCodeCacheDir();
     method public android.content.ContentResolver getContentResolver();
     method public java.io.File getDatabasePath(java.lang.String);
-    method public java.io.File getDeviceEncryptedFilesDir();
     method public java.io.File getDir(java.lang.String, int);
     method public java.io.File getExternalCacheDir();
     method public java.io.File[] getExternalCacheDirs();
@@ -8007,6 +8011,7 @@
     method public android.content.res.Resources getResources();
     method public android.content.SharedPreferences getSharedPreferences(java.lang.String, int);
     method public android.content.SharedPreferences getSharedPreferences(java.io.File, int);
+    method public java.io.File getSharedPreferencesPath(java.lang.String);
     method public java.lang.Object getSystemService(java.lang.String);
     method public java.lang.String getSystemServiceName(java.lang.Class<?>);
     method public android.content.res.Resources.Theme getTheme();
@@ -8014,6 +8019,7 @@
     method public deprecated int getWallpaperDesiredMinimumHeight();
     method public deprecated int getWallpaperDesiredMinimumWidth();
     method public void grantUriPermission(java.lang.String, android.net.Uri, int);
+    method public boolean isDeviceEncryptedStorage();
     method public java.io.FileInputStream openFileInput(java.lang.String) throws java.io.FileNotFoundException;
     method public java.io.FileOutputStream openFileOutput(java.lang.String, int) throws java.io.FileNotFoundException;
     method public android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase.CursorFactory);
@@ -8258,6 +8264,7 @@
     field public static final java.lang.String ACTION_APP_ERROR = "android.intent.action.APP_ERROR";
     field public static final java.lang.String ACTION_ASSIST = "android.intent.action.ASSIST";
     field public static final java.lang.String ACTION_ATTACH_DATA = "android.intent.action.ATTACH_DATA";
+    field public static final java.lang.String ACTION_AVAILABILITY_CHANGED = "android.intent.action.AVAILABILITY_CHANGED";
     field public static final java.lang.String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED";
     field public static final java.lang.String ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW";
     field public static final java.lang.String ACTION_BATTERY_OKAY = "android.intent.action.BATTERY_OKAY";
@@ -8297,6 +8304,7 @@
     field public static final java.lang.String ACTION_LOCKED_BOOT_COMPLETED = "android.intent.action.LOCKED_BOOT_COMPLETED";
     field public static final java.lang.String ACTION_MAIN = "android.intent.action.MAIN";
     field public static final java.lang.String ACTION_MANAGED_PROFILE_ADDED = "android.intent.action.MANAGED_PROFILE_ADDED";
+    field public static final java.lang.String ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED = "android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED";
     field public static final java.lang.String ACTION_MANAGED_PROFILE_REMOVED = "android.intent.action.MANAGED_PROFILE_REMOVED";
     field public static final java.lang.String ACTION_MANAGE_NETWORK_USAGE = "android.intent.action.MANAGE_NETWORK_USAGE";
     field public static final java.lang.String ACTION_MANAGE_PACKAGE_STORAGE = "android.intent.action.MANAGE_PACKAGE_STORAGE";
@@ -8441,6 +8449,7 @@
     field public static final java.lang.String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
     field public static final java.lang.String EXTRA_PROCESS_TEXT = "android.intent.extra.PROCESS_TEXT";
     field public static final java.lang.String EXTRA_PROCESS_TEXT_READONLY = "android.intent.extra.PROCESS_TEXT_READONLY";
+    field public static final java.lang.String EXTRA_QUIET_MODE = "android.intent.extra.QUIET_MODE";
     field public static final java.lang.String EXTRA_REFERRER = "android.intent.extra.REFERRER";
     field public static final java.lang.String EXTRA_REFERRER_NAME = "android.intent.extra.REFERRER_NAME";
     field public static final java.lang.String EXTRA_REMOTE_INTENT_TOKEN = "android.intent.extra.remote_intent_token";
@@ -9092,8 +9101,10 @@
     field public java.lang.String backupAgentName;
     field public java.lang.String className;
     field public int compatibleWidthLimitDp;
+    field public java.lang.String credentialEncryptedDataDir;
     field public java.lang.String dataDir;
     field public int descriptionRes;
+    field public java.lang.String deviceEncryptedDataDir;
     field public boolean enabled;
     field public int flags;
     field public int largestWidthLimitDp;
@@ -9415,6 +9426,8 @@
     method public abstract int getComponentEnabledSetting(android.content.ComponentName);
     method public abstract android.graphics.drawable.Drawable getDefaultActivityIcon();
     method public abstract android.graphics.drawable.Drawable getDrawable(java.lang.String, int, android.content.pm.ApplicationInfo);
+    method public abstract byte[] getEphemeralCookie();
+    method public abstract int getEphemeralCookieMaxSizeBytes();
     method public abstract java.util.List<android.content.pm.ApplicationInfo> getInstalledApplications(int);
     method public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int);
     method public abstract java.lang.String getInstallerPackageName(java.lang.String);
@@ -9446,6 +9459,7 @@
     method public abstract java.lang.CharSequence getUserBadgedLabel(java.lang.CharSequence, android.os.UserHandle);
     method public abstract android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
     method public abstract boolean hasSystemFeature(java.lang.String);
+    method public abstract boolean isEphemeralApplication();
     method public abstract boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
     method public abstract boolean isSafeMode();
     method public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
@@ -9463,6 +9477,7 @@
     method public abstract android.content.pm.ResolveInfo resolveService(android.content.Intent, int);
     method public abstract void setApplicationEnabledSetting(java.lang.String, int, int);
     method public abstract void setComponentEnabledSetting(android.content.ComponentName, int, int);
+    method public abstract boolean setEphemeralCookie(byte[]);
     method public abstract void setInstallerPackageName(java.lang.String, java.lang.String);
     method public abstract void verifyPendingInstall(int, int);
     field public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0; // 0x0
@@ -11527,6 +11542,7 @@
     field public static final int PRIVATE = 34; // 0x22
     field public static final int RAW10 = 37; // 0x25
     field public static final int RAW12 = 38; // 0x26
+    field public static final int RAW_PRIVATE = 36; // 0x24
     field public static final int RAW_SENSOR = 32; // 0x20
     field public static final int RGB_565 = 4; // 0x4
     field public static final int UNKNOWN = 0; // 0x0
@@ -20287,6 +20303,8 @@
     field public static final java.lang.String MIMETYPE_TEXT_CEA_608 = "text/cea-608";
     field public static final java.lang.String MIMETYPE_TEXT_VTT = "text/vtt";
     field public static final java.lang.String MIMETYPE_VIDEO_AVC = "video/avc";
+    field public static final java.lang.String MIMETYPE_VIDEO_DOLBY_AVC = "video/dolby-avc";
+    field public static final java.lang.String MIMETYPE_VIDEO_DOLBY_HEVC = "video/dolby-hevc";
     field public static final java.lang.String MIMETYPE_VIDEO_H263 = "video/3gpp";
     field public static final java.lang.String MIMETYPE_VIDEO_HEVC = "video/hevc";
     field public static final java.lang.String MIMETYPE_VIDEO_MPEG2 = "video/mpeg2";
@@ -20718,6 +20736,7 @@
   public static class MediaRouter.RouteInfo {
     method public android.media.MediaRouter.RouteCategory getCategory();
     method public java.lang.CharSequence getDescription();
+    method public int getDeviceType();
     method public android.media.MediaRouter.RouteGroup getGroup();
     method public android.graphics.drawable.Drawable getIconDrawable();
     method public java.lang.CharSequence getName();
@@ -20736,6 +20755,10 @@
     method public void requestSetVolume(int);
     method public void requestUpdateVolume(int);
     method public void setTag(java.lang.Object);
+    field public static final int DEVICE_TYPE_BLUETOOTH = 3; // 0x3
+    field public static final int DEVICE_TYPE_SPEAKER = 2; // 0x2
+    field public static final int DEVICE_TYPE_TV = 1; // 0x1
+    field public static final int DEVICE_TYPE_UNKNOWN = 0; // 0x0
     field public static final int PLAYBACK_TYPE_LOCAL = 0; // 0x0
     field public static final int PLAYBACK_TYPE_REMOTE = 1; // 0x1
     field public static final int PLAYBACK_VOLUME_FIXED = 0; // 0x0
@@ -28073,12 +28096,17 @@
     method public android.os.Bundle getUserRestrictions();
     method public android.os.Bundle getUserRestrictions(android.os.UserHandle);
     method public boolean hasUserRestriction(java.lang.String);
+    method public boolean isQuietModeEnabled(android.os.UserHandle);
     method public boolean isSystemUser();
     method public boolean isUserAGoat();
     method public boolean isUserRunning(android.os.UserHandle);
-    method public boolean isUserRunningAndLocked(android.os.UserHandle);
-    method public boolean isUserRunningAndUnlocked(android.os.UserHandle);
+    method public deprecated boolean isUserRunningAndLocked();
+    method public deprecated boolean isUserRunningAndLocked(android.os.UserHandle);
+    method public deprecated boolean isUserRunningAndUnlocked();
+    method public deprecated boolean isUserRunningAndUnlocked(android.os.UserHandle);
     method public boolean isUserRunningOrStopping(android.os.UserHandle);
+    method public boolean isUserUnlocked();
+    method public boolean isUserUnlocked(android.os.UserHandle);
     method public deprecated boolean setRestrictionsChallenge(java.lang.String);
     method public deprecated void setUserRestriction(java.lang.String, boolean);
     method public deprecated void setUserRestrictions(android.os.Bundle);
@@ -28464,6 +28492,7 @@
     method public android.preference.PreferenceScreen createPreferenceScreen(android.content.Context);
     method public android.preference.Preference findPreference(java.lang.CharSequence);
     method public static android.content.SharedPreferences getDefaultSharedPreferences(android.content.Context);
+    method public static java.lang.String getDefaultSharedPreferencesName(android.content.Context);
     method public android.content.SharedPreferences getSharedPreferences();
     method public int getSharedPreferencesMode();
     method public java.lang.String getSharedPreferencesName();
@@ -29676,6 +29705,7 @@
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/email_v2";
     field public static final android.net.Uri CONTENT_URI;
     field public static final java.lang.String DISPLAY_NAME = "data4";
+    field public static final android.net.Uri ENTERPRISE_CONTENT_FILTER_URI;
     field public static final android.net.Uri ENTERPRISE_CONTENT_LOOKUP_URI;
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
@@ -35197,6 +35227,7 @@
     field public static final java.lang.String KEY_VOICEMAIL_NOTIFICATION_PERSISTENT_BOOL = "voicemail_notification_persistent_bool";
     field public static final java.lang.String KEY_VOICE_PRIVACY_DISABLE_UI_BOOL = "voice_privacy_disable_ui_bool";
     field public static final java.lang.String KEY_VOLTE_REPLACEMENT_RAT_INT = "volte_replacement_rat_int";
+    field public static final java.lang.String KEY_VVM_CELLULAR_DATA_REQUIRED_BOOLEAN = "vvm_cellular_data_required";
     field public static final java.lang.String KEY_VVM_DESTINATION_NUMBER_STRING = "vvm_destination_number_string";
     field public static final java.lang.String KEY_VVM_PORT_NUMBER_INT = "vvm_port_number_int";
     field public static final java.lang.String KEY_VVM_TYPE_STRING = "vvm_type_string";
@@ -36227,6 +36258,7 @@
     method public int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
     method public void clearWallpaper();
     method public android.content.Context createConfigurationContext(android.content.res.Configuration);
+    method public android.content.Context createDeviceEncryptedStorageContext();
     method public android.content.Context createDisplayContext(android.view.Display);
     method public android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
     method public java.lang.String[] databaseList();
@@ -36248,7 +36280,6 @@
     method public java.io.File getCodeCacheDir();
     method public android.content.ContentResolver getContentResolver();
     method public java.io.File getDatabasePath(java.lang.String);
-    method public java.io.File getDeviceEncryptedFilesDir();
     method public java.io.File getDir(java.lang.String, int);
     method public java.io.File getExternalCacheDir();
     method public java.io.File[] getExternalCacheDirs();
@@ -36268,6 +36299,7 @@
     method public android.content.res.Resources getResources();
     method public android.content.SharedPreferences getSharedPreferences(java.lang.String, int);
     method public android.content.SharedPreferences getSharedPreferences(java.io.File, int);
+    method public java.io.File getSharedPreferencesPath(java.lang.String);
     method public java.lang.Object getSystemService(java.lang.String);
     method public java.lang.String getSystemServiceName(java.lang.Class<?>);
     method public android.content.res.Resources.Theme getTheme();
@@ -36275,6 +36307,7 @@
     method public int getWallpaperDesiredMinimumHeight();
     method public int getWallpaperDesiredMinimumWidth();
     method public void grantUriPermission(java.lang.String, android.net.Uri, int);
+    method public boolean isDeviceEncryptedStorage();
     method public java.io.FileInputStream openFileInput(java.lang.String) throws java.io.FileNotFoundException;
     method public java.io.FileOutputStream openFileOutput(java.lang.String, int) throws java.io.FileNotFoundException;
     method public android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase.CursorFactory);
@@ -36398,6 +36431,8 @@
     method public android.graphics.drawable.Drawable getDefaultActivityIcon();
     method public java.lang.String getDefaultBrowserPackageName(int);
     method public android.graphics.drawable.Drawable getDrawable(java.lang.String, int, android.content.pm.ApplicationInfo);
+    method public byte[] getEphemeralCookie();
+    method public int getEphemeralCookieMaxSizeBytes();
     method public java.util.List<android.content.pm.ApplicationInfo> getInstalledApplications(int);
     method public java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int);
     method public java.lang.String getInstallerPackageName(java.lang.String);
@@ -36428,6 +36463,7 @@
     method public java.lang.CharSequence getUserBadgedLabel(java.lang.CharSequence, android.os.UserHandle);
     method public android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
     method public boolean hasSystemFeature(java.lang.String);
+    method public boolean isEphemeralApplication();
     method public boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
     method public boolean isSafeMode();
     method public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
@@ -36446,6 +36482,7 @@
     method public void setApplicationEnabledSetting(java.lang.String, int, int);
     method public void setComponentEnabledSetting(android.content.ComponentName, int, int);
     method public boolean setDefaultBrowserPackageName(java.lang.String, int);
+    method public boolean setEphemeralCookie(byte[]);
     method public void setInstallerPackageName(java.lang.String, java.lang.String);
     method public void verifyPendingInstall(int, int);
   }
@@ -38672,9 +38709,9 @@
     method public int describeContents();
     method public static android.util.LocaleList forLanguageTags(java.lang.String);
     method public java.util.Locale get(int);
-    method public java.util.Locale getBestMatch(java.lang.String[]);
     method public static android.util.LocaleList getDefault();
     method public static android.util.LocaleList getEmptyLocaleList();
+    method public java.util.Locale getFirstMatch(java.lang.String[]);
     method public java.util.Locale getPrimary();
     method public boolean isEmpty();
     method public int size();
@@ -40216,6 +40253,7 @@
     field public static final int AXIS_RX = 12; // 0xc
     field public static final int AXIS_RY = 13; // 0xd
     field public static final int AXIS_RZ = 14; // 0xe
+    field public static final int AXIS_SCROLL = 26; // 0x1a
     field public static final int AXIS_SIZE = 3; // 0x3
     field public static final int AXIS_THROTTLE = 19; // 0x13
     field public static final int AXIS_TILT = 25; // 0x19
@@ -40524,7 +40562,6 @@
     method public android.view.accessibility.AccessibilityNodeInfo createAccessibilityNodeInfo();
     method public void createContextMenu(android.view.ContextMenu);
     method public void destroyDrawingCache();
-    method public final boolean didLayoutParamsChange();
     method public android.view.WindowInsets dispatchApplyWindowInsets(android.view.WindowInsets);
     method public void dispatchConfigurationChanged(android.content.res.Configuration);
     method public void dispatchDisplayHint(int);
@@ -40750,7 +40787,6 @@
     method public boolean isOpaque();
     method protected boolean isPaddingOffsetRequired();
     method public boolean isPaddingRelative();
-    method public final boolean isPartialLayoutRequested();
     method public boolean isPressed();
     method public boolean isSaveEnabled();
     method public boolean isSaveFromParentEnabled();
@@ -41362,7 +41398,6 @@
     method protected void dispatchThawSelfOnly(android.util.SparseArray<android.os.Parcelable>);
     method protected boolean drawChild(android.graphics.Canvas, android.view.View, long);
     method public void endViewTransition(android.view.View);
-    method public int findDependentLayoutAxes(android.view.View, int);
     method public android.view.View focusSearch(android.view.View, int);
     method public void focusableViewAvailable(android.view.View);
     method public boolean gatherTransparentRegion(android.graphics.Region);
@@ -41429,8 +41464,6 @@
     method public void requestChildFocus(android.view.View, android.view.View);
     method public boolean requestChildRectangleOnScreen(android.view.View, android.graphics.Rect, boolean);
     method public void requestDisallowInterceptTouchEvent(boolean);
-    method public void requestLayoutForChild(android.view.View);
-    method public void requestPartialLayoutForChild(android.view.View);
     method public boolean requestSendAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
     method public void requestTransparentRegion(android.view.View);
     method public void scheduleLayoutAnimation();
@@ -41545,7 +41578,6 @@
     method public abstract void childHasTransientStateChanged(android.view.View, boolean);
     method public abstract void clearChildFocus(android.view.View);
     method public abstract void createContextMenu(android.view.ContextMenu);
-    method public abstract int findDependentLayoutAxes(android.view.View, int);
     method public abstract android.view.View focusSearch(android.view.View, int);
     method public abstract void focusableViewAvailable(android.view.View);
     method public abstract boolean getChildVisibleRect(android.view.View, android.graphics.Rect, android.graphics.Point);
@@ -41575,16 +41607,12 @@
     method public abstract void requestDisallowInterceptTouchEvent(boolean);
     method public abstract void requestFitSystemWindows();
     method public abstract void requestLayout();
-    method public abstract void requestLayoutForChild(android.view.View);
     method public abstract boolean requestSendAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
     method public abstract void requestTransparentRegion(android.view.View);
     method public abstract boolean showContextMenuForChild(android.view.View);
     method public abstract boolean showContextMenuForChild(android.view.View, float, float);
     method public abstract android.view.ActionMode startActionModeForChild(android.view.View, android.view.ActionMode.Callback);
     method public abstract android.view.ActionMode startActionModeForChild(android.view.View, android.view.ActionMode.Callback, int);
-    field public static final int FLAG_LAYOUT_AXIS_ANY = 3; // 0x3
-    field public static final int FLAG_LAYOUT_AXIS_HORIZONTAL = 1; // 0x1
-    field public static final int FLAG_LAYOUT_AXIS_VERTICAL = 2; // 0x2
   }
 
   public class ViewPropertyAnimator {
@@ -41815,8 +41843,7 @@
     method public abstract void setContentView(int);
     method public abstract void setContentView(android.view.View);
     method public abstract void setContentView(android.view.View, android.view.ViewGroup.LayoutParams);
-    method public abstract void setDecorView(android.view.View);
-    method public abstract void setDecorView(int);
+    method public abstract void setDecorCaptionShade(int);
     method protected void setDefaultWindowFormat(int);
     method public void setDimAmount(float);
     method public void setElevation(float);
@@ -41837,6 +41864,8 @@
     method public void setMediaController(android.media.session.MediaController);
     method public abstract void setNavigationBarColor(int);
     method public void setReenterTransition(android.transition.Transition);
+    method public abstract void setResizingCaptionDrawable(android.graphics.drawable.Drawable);
+    method public final void setRestrictedCaptionAreaListener(android.view.Window.RestrictedCaptionAreaListener);
     method public void setReturnTransition(android.transition.Transition);
     method public void setSharedElementEnterTransition(android.transition.Transition);
     method public void setSharedElementExitTransition(android.transition.Transition);
@@ -41865,6 +41894,9 @@
     method public abstract void takeKeyEvents(boolean);
     method public abstract void takeSurface(android.view.SurfaceHolder.Callback2);
     method public abstract void togglePanel(int, android.view.KeyEvent);
+    field public static final int DECOR_CAPTION_SHADE_AUTO = 0; // 0x0
+    field public static final int DECOR_CAPTION_SHADE_DARK = 2; // 0x2
+    field public static final int DECOR_CAPTION_SHADE_LIGHT = 1; // 0x1
     field protected static final deprecated int DEFAULT_FEATURES = 65; // 0x41
     field public static final int FEATURE_ACTION_BAR = 8; // 0x8
     field public static final int FEATURE_ACTION_BAR_OVERLAY = 9; // 0x9
@@ -41919,6 +41951,10 @@
     method public abstract android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback, int);
   }
 
+  public static abstract interface Window.RestrictedCaptionAreaListener {
+    method public abstract void onRestrictedCaptionAreaChanged(android.graphics.Rect);
+  }
+
   public final class WindowAnimationFrameStats extends android.view.FrameStats implements android.os.Parcelable {
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
@@ -43183,7 +43219,8 @@
     method public java.lang.String getExtraValue();
     method public java.lang.String getExtraValueOf(java.lang.String);
     method public int getIconResId();
-    method public java.lang.String getLocale();
+    method public java.lang.String getLanguageTag();
+    method public deprecated java.lang.String getLocale();
     method public java.lang.String getMode();
     method public int getNameResId();
     method public boolean isAsciiCapable();
@@ -43198,6 +43235,7 @@
     method public android.view.inputmethod.InputMethodSubtype build();
     method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setIsAsciiCapable(boolean);
     method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setIsAuxiliary(boolean);
+    method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setLanguageTag(java.lang.String);
     method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setOverridesImplicitlyEnabledSubtype(boolean);
     method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setSubtypeExtraValue(java.lang.String);
     method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setSubtypeIconResId(int);
@@ -43255,13 +43293,14 @@
   }
 
   public final class SpellCheckerSubtype implements android.os.Parcelable {
-    ctor public SpellCheckerSubtype(int, java.lang.String, java.lang.String);
+    ctor public deprecated SpellCheckerSubtype(int, java.lang.String, java.lang.String);
     method public boolean containsExtraValueKey(java.lang.String);
     method public int describeContents();
     method public java.lang.CharSequence getDisplayName(android.content.Context, java.lang.String, android.content.pm.ApplicationInfo);
     method public java.lang.String getExtraValue();
     method public java.lang.String getExtraValueOf(java.lang.String);
-    method public java.lang.String getLocale();
+    method public java.lang.String getLanguageTag();
+    method public deprecated java.lang.String getLocale();
     method public int getNameResId();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.view.textservice.SpellCheckerSubtype> CREATOR;
@@ -49910,7 +49949,6 @@
   public abstract class Reference {
     method public void clear();
     method public boolean enqueue();
-    method public final synchronized boolean enqueueInternal();
     method public T get();
     method public boolean isEnqueued();
   }
@@ -64103,3 +64141,4 @@
   }
 
 }
+
diff --git a/api/system-current.txt b/api/system-current.txt
index bc7983a..15426c1 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -822,6 +822,7 @@
     field public static final int label = 16842753; // 0x1010001
     field public static final int labelFor = 16843718; // 0x10103c6
     field public static final int labelTextSize = 16843317; // 0x1010235
+    field public static final int languageTag = 16844041; // 0x1010509
     field public static final int largeHeap = 16843610; // 0x101035a
     field public static final int largeScreens = 16843398; // 0x1010286
     field public static final int largestWidthLimitDp = 16843622; // 0x1010366
@@ -5935,6 +5936,7 @@
     method public void notifyPendingSystemUpdate(long);
     method public void removeActiveAdmin(android.content.ComponentName);
     method public boolean removeCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
+    method public boolean removeKeyPair(android.content.ComponentName, java.lang.String);
     method public boolean removeUser(android.content.ComponentName, android.os.UserHandle);
     method public boolean resetPassword(java.lang.String, int);
     method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean);
@@ -8023,6 +8025,8 @@
     method public abstract int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
     method public abstract deprecated void clearWallpaper() throws java.io.IOException;
     method public abstract android.content.Context createConfigurationContext(android.content.res.Configuration);
+    method public abstract android.content.Context createCredentialEncryptedStorageContext();
+    method public abstract android.content.Context createDeviceEncryptedStorageContext();
     method public abstract android.content.Context createDisplayContext(android.view.Display);
     method public abstract android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
     method public abstract java.lang.String[] databaseList();
@@ -8045,9 +8049,7 @@
     method public final int getColor(int);
     method public final android.content.res.ColorStateList getColorStateList(int);
     method public abstract android.content.ContentResolver getContentResolver();
-    method public abstract java.io.File getCredentialEncryptedFilesDir();
     method public abstract java.io.File getDatabasePath(java.lang.String);
-    method public abstract java.io.File getDeviceEncryptedFilesDir();
     method public abstract java.io.File getDir(java.lang.String, int);
     method public final android.graphics.drawable.Drawable getDrawable(int);
     method public abstract java.io.File getExternalCacheDir();
@@ -8068,6 +8070,7 @@
     method public abstract android.content.res.Resources getResources();
     method public abstract android.content.SharedPreferences getSharedPreferences(java.lang.String, int);
     method public abstract android.content.SharedPreferences getSharedPreferences(java.io.File, int);
+    method public abstract java.io.File getSharedPreferencesPath(java.lang.String);
     method public final java.lang.String getString(int);
     method public final java.lang.String getString(int, java.lang.Object...);
     method public abstract java.lang.Object getSystemService(java.lang.String);
@@ -8079,6 +8082,8 @@
     method public abstract deprecated int getWallpaperDesiredMinimumHeight();
     method public abstract deprecated int getWallpaperDesiredMinimumWidth();
     method public abstract void grantUriPermission(java.lang.String, android.net.Uri, int);
+    method public abstract boolean isCredentialEncryptedStorage();
+    method public abstract boolean isDeviceEncryptedStorage();
     method public boolean isRestricted();
     method public final android.content.res.TypedArray obtainStyledAttributes(int[]);
     method public final android.content.res.TypedArray obtainStyledAttributes(int, int[]) throws android.content.res.Resources.NotFoundException;
@@ -8218,6 +8223,8 @@
     method public int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
     method public deprecated void clearWallpaper() throws java.io.IOException;
     method public android.content.Context createConfigurationContext(android.content.res.Configuration);
+    method public android.content.Context createCredentialEncryptedStorageContext();
+    method public android.content.Context createDeviceEncryptedStorageContext();
     method public android.content.Context createDisplayContext(android.view.Display);
     method public android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
     method public java.lang.String[] databaseList();
@@ -8239,9 +8246,7 @@
     method public java.lang.ClassLoader getClassLoader();
     method public java.io.File getCodeCacheDir();
     method public android.content.ContentResolver getContentResolver();
-    method public java.io.File getCredentialEncryptedFilesDir();
     method public java.io.File getDatabasePath(java.lang.String);
-    method public java.io.File getDeviceEncryptedFilesDir();
     method public java.io.File getDir(java.lang.String, int);
     method public java.io.File getExternalCacheDir();
     method public java.io.File[] getExternalCacheDirs();
@@ -8261,6 +8266,7 @@
     method public android.content.res.Resources getResources();
     method public android.content.SharedPreferences getSharedPreferences(java.lang.String, int);
     method public android.content.SharedPreferences getSharedPreferences(java.io.File, int);
+    method public java.io.File getSharedPreferencesPath(java.lang.String);
     method public java.lang.Object getSystemService(java.lang.String);
     method public java.lang.String getSystemServiceName(java.lang.Class<?>);
     method public android.content.res.Resources.Theme getTheme();
@@ -8268,6 +8274,8 @@
     method public deprecated int getWallpaperDesiredMinimumHeight();
     method public deprecated int getWallpaperDesiredMinimumWidth();
     method public void grantUriPermission(java.lang.String, android.net.Uri, int);
+    method public boolean isCredentialEncryptedStorage();
+    method public boolean isDeviceEncryptedStorage();
     method public java.io.FileInputStream openFileInput(java.lang.String) throws java.io.FileNotFoundException;
     method public java.io.FileOutputStream openFileOutput(java.lang.String, int) throws java.io.FileNotFoundException;
     method public android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase.CursorFactory);
@@ -8514,6 +8522,7 @@
     field public static final java.lang.String ACTION_APP_ERROR = "android.intent.action.APP_ERROR";
     field public static final java.lang.String ACTION_ASSIST = "android.intent.action.ASSIST";
     field public static final java.lang.String ACTION_ATTACH_DATA = "android.intent.action.ATTACH_DATA";
+    field public static final java.lang.String ACTION_AVAILABILITY_CHANGED = "android.intent.action.AVAILABILITY_CHANGED";
     field public static final java.lang.String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED";
     field public static final java.lang.String ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW";
     field public static final java.lang.String ACTION_BATTERY_OKAY = "android.intent.action.BATTERY_OKAY";
@@ -8555,6 +8564,7 @@
     field public static final java.lang.String ACTION_LOCKED_BOOT_COMPLETED = "android.intent.action.LOCKED_BOOT_COMPLETED";
     field public static final java.lang.String ACTION_MAIN = "android.intent.action.MAIN";
     field public static final java.lang.String ACTION_MANAGED_PROFILE_ADDED = "android.intent.action.MANAGED_PROFILE_ADDED";
+    field public static final java.lang.String ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED = "android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED";
     field public static final java.lang.String ACTION_MANAGED_PROFILE_REMOVED = "android.intent.action.MANAGED_PROFILE_REMOVED";
     field public static final java.lang.String ACTION_MANAGE_NETWORK_USAGE = "android.intent.action.MANAGE_NETWORK_USAGE";
     field public static final java.lang.String ACTION_MANAGE_PACKAGE_STORAGE = "android.intent.action.MANAGE_PACKAGE_STORAGE";
@@ -8705,6 +8715,7 @@
     field public static final java.lang.String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
     field public static final java.lang.String EXTRA_PROCESS_TEXT = "android.intent.extra.PROCESS_TEXT";
     field public static final java.lang.String EXTRA_PROCESS_TEXT_READONLY = "android.intent.extra.PROCESS_TEXT_READONLY";
+    field public static final java.lang.String EXTRA_QUIET_MODE = "android.intent.extra.QUIET_MODE";
     field public static final java.lang.String EXTRA_REFERRER = "android.intent.extra.REFERRER";
     field public static final java.lang.String EXTRA_REFERRER_NAME = "android.intent.extra.REFERRER_NAME";
     field public static final java.lang.String EXTRA_REMOTE_INTENT_TOKEN = "android.intent.extra.remote_intent_token";
@@ -9356,8 +9367,10 @@
     field public java.lang.String backupAgentName;
     field public java.lang.String className;
     field public int compatibleWidthLimitDp;
+    field public java.lang.String credentialEncryptedDataDir;
     field public java.lang.String dataDir;
     field public int descriptionRes;
+    field public java.lang.String deviceEncryptedDataDir;
     field public boolean enabled;
     field public int flags;
     field public int largestWidthLimitDp;
@@ -9707,6 +9720,8 @@
     method public abstract int getComponentEnabledSetting(android.content.ComponentName);
     method public abstract android.graphics.drawable.Drawable getDefaultActivityIcon();
     method public abstract android.graphics.drawable.Drawable getDrawable(java.lang.String, int, android.content.pm.ApplicationInfo);
+    method public abstract byte[] getEphemeralCookie();
+    method public abstract int getEphemeralCookieMaxSizeBytes();
     method public abstract java.util.List<android.content.pm.ApplicationInfo> getInstalledApplications(int);
     method public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int);
     method public abstract java.lang.String getInstallerPackageName(java.lang.String);
@@ -9740,6 +9755,7 @@
     method public abstract android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
     method public abstract void grantRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle);
     method public abstract boolean hasSystemFeature(java.lang.String);
+    method public abstract boolean isEphemeralApplication();
     method public abstract boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
     method public abstract boolean isSafeMode();
     method public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
@@ -9759,6 +9775,7 @@
     method public abstract void revokeRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle);
     method public abstract void setApplicationEnabledSetting(java.lang.String, int, int);
     method public abstract void setComponentEnabledSetting(android.content.ComponentName, int, int);
+    method public abstract boolean setEphemeralCookie(byte[]);
     method public abstract void setInstallerPackageName(java.lang.String, java.lang.String);
     method public abstract void updatePermissionFlags(java.lang.String, java.lang.String, int, int, android.os.UserHandle);
     method public abstract void verifyIntentFilter(int, int, java.util.List<java.lang.String>);
@@ -11872,6 +11889,7 @@
     field public static final int PRIVATE = 34; // 0x22
     field public static final int RAW10 = 37; // 0x25
     field public static final int RAW12 = 38; // 0x26
+    field public static final int RAW_PRIVATE = 36; // 0x24
     field public static final int RAW_SENSOR = 32; // 0x20
     field public static final int RGB_565 = 4; // 0x4
     field public static final int UNKNOWN = 0; // 0x0
@@ -21399,7 +21417,6 @@
     method public void setOnKeyStatusChangeListener(android.media.MediaDrm.OnKeyStatusChangeListener, android.os.Handler);
     method public void setPropertyByteArray(java.lang.String, byte[]);
     method public void setPropertyString(java.lang.String, java.lang.String);
-    method public void unprovisionDevice();
     field public static final int EVENT_KEY_EXPIRED = 3; // 0x3
     field public static final int EVENT_KEY_REQUIRED = 2; // 0x2
     field public static final deprecated int EVENT_PROVISION_REQUIRED = 1; // 0x1
@@ -21577,6 +21594,8 @@
     field public static final java.lang.String MIMETYPE_TEXT_CEA_608 = "text/cea-608";
     field public static final java.lang.String MIMETYPE_TEXT_VTT = "text/vtt";
     field public static final java.lang.String MIMETYPE_VIDEO_AVC = "video/avc";
+    field public static final java.lang.String MIMETYPE_VIDEO_DOLBY_AVC = "video/dolby-avc";
+    field public static final java.lang.String MIMETYPE_VIDEO_DOLBY_HEVC = "video/dolby-hevc";
     field public static final java.lang.String MIMETYPE_VIDEO_H263 = "video/3gpp";
     field public static final java.lang.String MIMETYPE_VIDEO_HEVC = "video/hevc";
     field public static final java.lang.String MIMETYPE_VIDEO_MPEG2 = "video/mpeg2";
@@ -22010,6 +22029,7 @@
   public static class MediaRouter.RouteInfo {
     method public android.media.MediaRouter.RouteCategory getCategory();
     method public java.lang.CharSequence getDescription();
+    method public int getDeviceType();
     method public android.media.MediaRouter.RouteGroup getGroup();
     method public android.graphics.drawable.Drawable getIconDrawable();
     method public java.lang.CharSequence getName();
@@ -22028,6 +22048,10 @@
     method public void requestSetVolume(int);
     method public void requestUpdateVolume(int);
     method public void setTag(java.lang.Object);
+    field public static final int DEVICE_TYPE_BLUETOOTH = 3; // 0x3
+    field public static final int DEVICE_TYPE_SPEAKER = 2; // 0x2
+    field public static final int DEVICE_TYPE_TV = 1; // 0x1
+    field public static final int DEVICE_TYPE_UNKNOWN = 0; // 0x0
     field public static final int PLAYBACK_TYPE_LOCAL = 0; // 0x0
     field public static final int PLAYBACK_TYPE_REMOTE = 1; // 0x1
     field public static final int PLAYBACK_VOLUME_FIXED = 0; // 0x0
@@ -30066,12 +30090,17 @@
     method public android.os.Bundle getUserRestrictions(android.os.UserHandle);
     method public boolean hasUserRestriction(java.lang.String);
     method public boolean isManagedProfile();
+    method public boolean isQuietModeEnabled(android.os.UserHandle);
     method public boolean isSystemUser();
     method public boolean isUserAGoat();
     method public boolean isUserRunning(android.os.UserHandle);
-    method public boolean isUserRunningAndLocked(android.os.UserHandle);
-    method public boolean isUserRunningAndUnlocked(android.os.UserHandle);
+    method public deprecated boolean isUserRunningAndLocked();
+    method public deprecated boolean isUserRunningAndLocked(android.os.UserHandle);
+    method public deprecated boolean isUserRunningAndUnlocked();
+    method public deprecated boolean isUserRunningAndUnlocked(android.os.UserHandle);
     method public boolean isUserRunningOrStopping(android.os.UserHandle);
+    method public boolean isUserUnlocked();
+    method public boolean isUserUnlocked(android.os.UserHandle);
     method public deprecated boolean setRestrictionsChallenge(java.lang.String);
     method public deprecated void setUserRestriction(java.lang.String, boolean);
     method public deprecated void setUserRestrictions(android.os.Bundle);
@@ -30457,6 +30486,7 @@
     method public android.preference.PreferenceScreen createPreferenceScreen(android.content.Context);
     method public android.preference.Preference findPreference(java.lang.CharSequence);
     method public static android.content.SharedPreferences getDefaultSharedPreferences(android.content.Context);
+    method public static java.lang.String getDefaultSharedPreferencesName(android.content.Context);
     method public android.content.SharedPreferences getSharedPreferences();
     method public int getSharedPreferencesMode();
     method public java.lang.String getSharedPreferencesName();
@@ -31669,6 +31699,7 @@
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/email_v2";
     field public static final android.net.Uri CONTENT_URI;
     field public static final java.lang.String DISPLAY_NAME = "data4";
+    field public static final android.net.Uri ENTERPRISE_CONTENT_FILTER_URI;
     field public static final android.net.Uri ENTERPRISE_CONTENT_LOOKUP_URI;
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
@@ -37469,6 +37500,7 @@
     field public static final java.lang.String KEY_VOICEMAIL_NOTIFICATION_PERSISTENT_BOOL = "voicemail_notification_persistent_bool";
     field public static final java.lang.String KEY_VOICE_PRIVACY_DISABLE_UI_BOOL = "voice_privacy_disable_ui_bool";
     field public static final java.lang.String KEY_VOLTE_REPLACEMENT_RAT_INT = "volte_replacement_rat_int";
+    field public static final java.lang.String KEY_VVM_CELLULAR_DATA_REQUIRED_BOOLEAN = "vvm_cellular_data_required";
     field public static final java.lang.String KEY_VVM_DESTINATION_NUMBER_STRING = "vvm_destination_number_string";
     field public static final java.lang.String KEY_VVM_PORT_NUMBER_INT = "vvm_port_number_int";
     field public static final java.lang.String KEY_VVM_TYPE_STRING = "vvm_type_string";
@@ -38553,6 +38585,8 @@
     method public int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
     method public void clearWallpaper();
     method public android.content.Context createConfigurationContext(android.content.res.Configuration);
+    method public android.content.Context createCredentialEncryptedStorageContext();
+    method public android.content.Context createDeviceEncryptedStorageContext();
     method public android.content.Context createDisplayContext(android.view.Display);
     method public android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
     method public java.lang.String[] databaseList();
@@ -38573,9 +38607,7 @@
     method public java.lang.ClassLoader getClassLoader();
     method public java.io.File getCodeCacheDir();
     method public android.content.ContentResolver getContentResolver();
-    method public java.io.File getCredentialEncryptedFilesDir();
     method public java.io.File getDatabasePath(java.lang.String);
-    method public java.io.File getDeviceEncryptedFilesDir();
     method public java.io.File getDir(java.lang.String, int);
     method public java.io.File getExternalCacheDir();
     method public java.io.File[] getExternalCacheDirs();
@@ -38595,6 +38627,7 @@
     method public android.content.res.Resources getResources();
     method public android.content.SharedPreferences getSharedPreferences(java.lang.String, int);
     method public android.content.SharedPreferences getSharedPreferences(java.io.File, int);
+    method public java.io.File getSharedPreferencesPath(java.lang.String);
     method public java.lang.Object getSystemService(java.lang.String);
     method public java.lang.String getSystemServiceName(java.lang.Class<?>);
     method public android.content.res.Resources.Theme getTheme();
@@ -38602,6 +38635,8 @@
     method public int getWallpaperDesiredMinimumHeight();
     method public int getWallpaperDesiredMinimumWidth();
     method public void grantUriPermission(java.lang.String, android.net.Uri, int);
+    method public boolean isCredentialEncryptedStorage();
+    method public boolean isDeviceEncryptedStorage();
     method public java.io.FileInputStream openFileInput(java.lang.String) throws java.io.FileNotFoundException;
     method public java.io.FileOutputStream openFileOutput(java.lang.String, int) throws java.io.FileNotFoundException;
     method public android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase.CursorFactory);
@@ -38728,6 +38763,8 @@
     method public android.graphics.drawable.Drawable getDefaultActivityIcon();
     method public java.lang.String getDefaultBrowserPackageName(int);
     method public android.graphics.drawable.Drawable getDrawable(java.lang.String, int, android.content.pm.ApplicationInfo);
+    method public byte[] getEphemeralCookie();
+    method public int getEphemeralCookieMaxSizeBytes();
     method public java.util.List<android.content.pm.ApplicationInfo> getInstalledApplications(int);
     method public java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int);
     method public java.lang.String getInstallerPackageName(java.lang.String);
@@ -38760,6 +38797,7 @@
     method public android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
     method public void grantRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle);
     method public boolean hasSystemFeature(java.lang.String);
+    method public boolean isEphemeralApplication();
     method public boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
     method public boolean isSafeMode();
     method public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
@@ -38780,6 +38818,7 @@
     method public void setApplicationEnabledSetting(java.lang.String, int, int);
     method public void setComponentEnabledSetting(android.content.ComponentName, int, int);
     method public boolean setDefaultBrowserPackageName(java.lang.String, int);
+    method public boolean setEphemeralCookie(byte[]);
     method public void setInstallerPackageName(java.lang.String, java.lang.String);
     method public void updatePermissionFlags(java.lang.String, java.lang.String, int, int, android.os.UserHandle);
     method public void verifyIntentFilter(int, int, java.util.List<java.lang.String>);
@@ -41008,9 +41047,9 @@
     method public int describeContents();
     method public static android.util.LocaleList forLanguageTags(java.lang.String);
     method public java.util.Locale get(int);
-    method public java.util.Locale getBestMatch(java.lang.String[]);
     method public static android.util.LocaleList getDefault();
     method public static android.util.LocaleList getEmptyLocaleList();
+    method public java.util.Locale getFirstMatch(java.lang.String[]);
     method public java.util.Locale getPrimary();
     method public boolean isEmpty();
     method public int size();
@@ -42552,6 +42591,7 @@
     field public static final int AXIS_RX = 12; // 0xc
     field public static final int AXIS_RY = 13; // 0xd
     field public static final int AXIS_RZ = 14; // 0xe
+    field public static final int AXIS_SCROLL = 26; // 0x1a
     field public static final int AXIS_SIZE = 3; // 0x3
     field public static final int AXIS_THROTTLE = 19; // 0x13
     field public static final int AXIS_TILT = 25; // 0x19
@@ -42860,7 +42900,6 @@
     method public android.view.accessibility.AccessibilityNodeInfo createAccessibilityNodeInfo();
     method public void createContextMenu(android.view.ContextMenu);
     method public void destroyDrawingCache();
-    method public final boolean didLayoutParamsChange();
     method public android.view.WindowInsets dispatchApplyWindowInsets(android.view.WindowInsets);
     method public void dispatchConfigurationChanged(android.content.res.Configuration);
     method public void dispatchDisplayHint(int);
@@ -43086,7 +43125,6 @@
     method public boolean isOpaque();
     method protected boolean isPaddingOffsetRequired();
     method public boolean isPaddingRelative();
-    method public final boolean isPartialLayoutRequested();
     method public boolean isPressed();
     method public boolean isSaveEnabled();
     method public boolean isSaveFromParentEnabled();
@@ -43698,7 +43736,6 @@
     method protected void dispatchThawSelfOnly(android.util.SparseArray<android.os.Parcelable>);
     method protected boolean drawChild(android.graphics.Canvas, android.view.View, long);
     method public void endViewTransition(android.view.View);
-    method public int findDependentLayoutAxes(android.view.View, int);
     method public android.view.View focusSearch(android.view.View, int);
     method public void focusableViewAvailable(android.view.View);
     method public boolean gatherTransparentRegion(android.graphics.Region);
@@ -43765,8 +43802,6 @@
     method public void requestChildFocus(android.view.View, android.view.View);
     method public boolean requestChildRectangleOnScreen(android.view.View, android.graphics.Rect, boolean);
     method public void requestDisallowInterceptTouchEvent(boolean);
-    method public void requestLayoutForChild(android.view.View);
-    method public void requestPartialLayoutForChild(android.view.View);
     method public boolean requestSendAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
     method public void requestTransparentRegion(android.view.View);
     method public void scheduleLayoutAnimation();
@@ -43881,7 +43916,6 @@
     method public abstract void childHasTransientStateChanged(android.view.View, boolean);
     method public abstract void clearChildFocus(android.view.View);
     method public abstract void createContextMenu(android.view.ContextMenu);
-    method public abstract int findDependentLayoutAxes(android.view.View, int);
     method public abstract android.view.View focusSearch(android.view.View, int);
     method public abstract void focusableViewAvailable(android.view.View);
     method public abstract boolean getChildVisibleRect(android.view.View, android.graphics.Rect, android.graphics.Point);
@@ -43911,16 +43945,12 @@
     method public abstract void requestDisallowInterceptTouchEvent(boolean);
     method public abstract void requestFitSystemWindows();
     method public abstract void requestLayout();
-    method public abstract void requestLayoutForChild(android.view.View);
     method public abstract boolean requestSendAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
     method public abstract void requestTransparentRegion(android.view.View);
     method public abstract boolean showContextMenuForChild(android.view.View);
     method public abstract boolean showContextMenuForChild(android.view.View, float, float);
     method public abstract android.view.ActionMode startActionModeForChild(android.view.View, android.view.ActionMode.Callback);
     method public abstract android.view.ActionMode startActionModeForChild(android.view.View, android.view.ActionMode.Callback, int);
-    field public static final int FLAG_LAYOUT_AXIS_ANY = 3; // 0x3
-    field public static final int FLAG_LAYOUT_AXIS_HORIZONTAL = 1; // 0x1
-    field public static final int FLAG_LAYOUT_AXIS_VERTICAL = 2; // 0x2
   }
 
   public class ViewPropertyAnimator {
@@ -44151,8 +44181,7 @@
     method public abstract void setContentView(int);
     method public abstract void setContentView(android.view.View);
     method public abstract void setContentView(android.view.View, android.view.ViewGroup.LayoutParams);
-    method public abstract void setDecorView(android.view.View);
-    method public abstract void setDecorView(int);
+    method public abstract void setDecorCaptionShade(int);
     method protected void setDefaultWindowFormat(int);
     method public void setDimAmount(float);
     method public void setDisableWallpaperTouchEvents(boolean);
@@ -44174,6 +44203,8 @@
     method public void setMediaController(android.media.session.MediaController);
     method public abstract void setNavigationBarColor(int);
     method public void setReenterTransition(android.transition.Transition);
+    method public abstract void setResizingCaptionDrawable(android.graphics.drawable.Drawable);
+    method public final void setRestrictedCaptionAreaListener(android.view.Window.RestrictedCaptionAreaListener);
     method public void setReturnTransition(android.transition.Transition);
     method public void setSharedElementEnterTransition(android.transition.Transition);
     method public void setSharedElementExitTransition(android.transition.Transition);
@@ -44202,6 +44233,9 @@
     method public abstract void takeKeyEvents(boolean);
     method public abstract void takeSurface(android.view.SurfaceHolder.Callback2);
     method public abstract void togglePanel(int, android.view.KeyEvent);
+    field public static final int DECOR_CAPTION_SHADE_AUTO = 0; // 0x0
+    field public static final int DECOR_CAPTION_SHADE_DARK = 2; // 0x2
+    field public static final int DECOR_CAPTION_SHADE_LIGHT = 1; // 0x1
     field protected static final deprecated int DEFAULT_FEATURES = 65; // 0x41
     field public static final int FEATURE_ACTION_BAR = 8; // 0x8
     field public static final int FEATURE_ACTION_BAR_OVERLAY = 9; // 0x9
@@ -44256,6 +44290,10 @@
     method public abstract android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback, int);
   }
 
+  public static abstract interface Window.RestrictedCaptionAreaListener {
+    method public abstract void onRestrictedCaptionAreaChanged(android.graphics.Rect);
+  }
+
   public final class WindowAnimationFrameStats extends android.view.FrameStats implements android.os.Parcelable {
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
@@ -45522,7 +45560,8 @@
     method public java.lang.String getExtraValue();
     method public java.lang.String getExtraValueOf(java.lang.String);
     method public int getIconResId();
-    method public java.lang.String getLocale();
+    method public java.lang.String getLanguageTag();
+    method public deprecated java.lang.String getLocale();
     method public java.lang.String getMode();
     method public int getNameResId();
     method public boolean isAsciiCapable();
@@ -45537,6 +45576,7 @@
     method public android.view.inputmethod.InputMethodSubtype build();
     method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setIsAsciiCapable(boolean);
     method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setIsAuxiliary(boolean);
+    method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setLanguageTag(java.lang.String);
     method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setOverridesImplicitlyEnabledSubtype(boolean);
     method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setSubtypeExtraValue(java.lang.String);
     method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setSubtypeIconResId(int);
@@ -45594,13 +45634,14 @@
   }
 
   public final class SpellCheckerSubtype implements android.os.Parcelable {
-    ctor public SpellCheckerSubtype(int, java.lang.String, java.lang.String);
+    ctor public deprecated SpellCheckerSubtype(int, java.lang.String, java.lang.String);
     method public boolean containsExtraValueKey(java.lang.String);
     method public int describeContents();
     method public java.lang.CharSequence getDisplayName(android.content.Context, java.lang.String, android.content.pm.ApplicationInfo);
     method public java.lang.String getExtraValue();
     method public java.lang.String getExtraValueOf(java.lang.String);
-    method public java.lang.String getLocale();
+    method public java.lang.String getLanguageTag();
+    method public deprecated java.lang.String getLocale();
     method public int getNameResId();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.view.textservice.SpellCheckerSubtype> CREATOR;
@@ -52562,7 +52603,6 @@
   public abstract class Reference {
     method public void clear();
     method public boolean enqueue();
-    method public final synchronized boolean enqueueInternal();
     method public T get();
     method public boolean isEnqueued();
   }
diff --git a/api/test-current.txt b/api/test-current.txt
index 3bcfd67..029073c 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -728,6 +728,7 @@
     field public static final int label = 16842753; // 0x1010001
     field public static final int labelFor = 16843718; // 0x10103c6
     field public static final int labelTextSize = 16843317; // 0x1010235
+    field public static final int languageTag = 16844041; // 0x1010509
     field public static final int largeHeap = 16843610; // 0x101035a
     field public static final int largeScreens = 16843398; // 0x1010286
     field public static final int largestWidthLimitDp = 16843622; // 0x1010366
@@ -5802,6 +5803,7 @@
     method public void lockNow();
     method public void removeActiveAdmin(android.content.ComponentName);
     method public boolean removeCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
+    method public boolean removeKeyPair(android.content.ComponentName, java.lang.String);
     method public boolean removeUser(android.content.ComponentName, android.os.UserHandle);
     method public boolean resetPassword(java.lang.String, int);
     method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean);
@@ -7779,6 +7781,7 @@
     method public abstract int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
     method public abstract deprecated void clearWallpaper() throws java.io.IOException;
     method public abstract android.content.Context createConfigurationContext(android.content.res.Configuration);
+    method public abstract android.content.Context createDeviceEncryptedStorageContext();
     method public abstract android.content.Context createDisplayContext(android.view.Display);
     method public abstract android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
     method public abstract java.lang.String[] databaseList();
@@ -7802,7 +7805,6 @@
     method public final android.content.res.ColorStateList getColorStateList(int);
     method public abstract android.content.ContentResolver getContentResolver();
     method public abstract java.io.File getDatabasePath(java.lang.String);
-    method public abstract java.io.File getDeviceEncryptedFilesDir();
     method public abstract java.io.File getDir(java.lang.String, int);
     method public final android.graphics.drawable.Drawable getDrawable(int);
     method public abstract java.io.File getExternalCacheDir();
@@ -7823,6 +7825,7 @@
     method public abstract android.content.res.Resources getResources();
     method public abstract android.content.SharedPreferences getSharedPreferences(java.lang.String, int);
     method public abstract android.content.SharedPreferences getSharedPreferences(java.io.File, int);
+    method public abstract java.io.File getSharedPreferencesPath(java.lang.String);
     method public final java.lang.String getString(int);
     method public final java.lang.String getString(int, java.lang.Object...);
     method public abstract java.lang.Object getSystemService(java.lang.String);
@@ -7834,6 +7837,7 @@
     method public abstract deprecated int getWallpaperDesiredMinimumHeight();
     method public abstract deprecated int getWallpaperDesiredMinimumWidth();
     method public abstract void grantUriPermission(java.lang.String, android.net.Uri, int);
+    method public abstract boolean isDeviceEncryptedStorage();
     method public boolean isRestricted();
     method public final android.content.res.TypedArray obtainStyledAttributes(int[]);
     method public final android.content.res.TypedArray obtainStyledAttributes(int, int[]) throws android.content.res.Resources.NotFoundException;
@@ -7965,6 +7969,7 @@
     method public int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
     method public deprecated void clearWallpaper() throws java.io.IOException;
     method public android.content.Context createConfigurationContext(android.content.res.Configuration);
+    method public android.content.Context createDeviceEncryptedStorageContext();
     method public android.content.Context createDisplayContext(android.view.Display);
     method public android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
     method public java.lang.String[] databaseList();
@@ -7987,7 +7992,6 @@
     method public java.io.File getCodeCacheDir();
     method public android.content.ContentResolver getContentResolver();
     method public java.io.File getDatabasePath(java.lang.String);
-    method public java.io.File getDeviceEncryptedFilesDir();
     method public java.io.File getDir(java.lang.String, int);
     method public java.io.File getExternalCacheDir();
     method public java.io.File[] getExternalCacheDirs();
@@ -8007,6 +8011,7 @@
     method public android.content.res.Resources getResources();
     method public android.content.SharedPreferences getSharedPreferences(java.lang.String, int);
     method public android.content.SharedPreferences getSharedPreferences(java.io.File, int);
+    method public java.io.File getSharedPreferencesPath(java.lang.String);
     method public java.lang.Object getSystemService(java.lang.String);
     method public java.lang.String getSystemServiceName(java.lang.Class<?>);
     method public android.content.res.Resources.Theme getTheme();
@@ -8014,6 +8019,7 @@
     method public deprecated int getWallpaperDesiredMinimumHeight();
     method public deprecated int getWallpaperDesiredMinimumWidth();
     method public void grantUriPermission(java.lang.String, android.net.Uri, int);
+    method public boolean isDeviceEncryptedStorage();
     method public java.io.FileInputStream openFileInput(java.lang.String) throws java.io.FileNotFoundException;
     method public java.io.FileOutputStream openFileOutput(java.lang.String, int) throws java.io.FileNotFoundException;
     method public android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase.CursorFactory);
@@ -8258,6 +8264,7 @@
     field public static final java.lang.String ACTION_APP_ERROR = "android.intent.action.APP_ERROR";
     field public static final java.lang.String ACTION_ASSIST = "android.intent.action.ASSIST";
     field public static final java.lang.String ACTION_ATTACH_DATA = "android.intent.action.ATTACH_DATA";
+    field public static final java.lang.String ACTION_AVAILABILITY_CHANGED = "android.intent.action.AVAILABILITY_CHANGED";
     field public static final java.lang.String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED";
     field public static final java.lang.String ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW";
     field public static final java.lang.String ACTION_BATTERY_OKAY = "android.intent.action.BATTERY_OKAY";
@@ -8297,6 +8304,7 @@
     field public static final java.lang.String ACTION_LOCKED_BOOT_COMPLETED = "android.intent.action.LOCKED_BOOT_COMPLETED";
     field public static final java.lang.String ACTION_MAIN = "android.intent.action.MAIN";
     field public static final java.lang.String ACTION_MANAGED_PROFILE_ADDED = "android.intent.action.MANAGED_PROFILE_ADDED";
+    field public static final java.lang.String ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED = "android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED";
     field public static final java.lang.String ACTION_MANAGED_PROFILE_REMOVED = "android.intent.action.MANAGED_PROFILE_REMOVED";
     field public static final java.lang.String ACTION_MANAGE_NETWORK_USAGE = "android.intent.action.MANAGE_NETWORK_USAGE";
     field public static final java.lang.String ACTION_MANAGE_PACKAGE_STORAGE = "android.intent.action.MANAGE_PACKAGE_STORAGE";
@@ -8441,6 +8449,7 @@
     field public static final java.lang.String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
     field public static final java.lang.String EXTRA_PROCESS_TEXT = "android.intent.extra.PROCESS_TEXT";
     field public static final java.lang.String EXTRA_PROCESS_TEXT_READONLY = "android.intent.extra.PROCESS_TEXT_READONLY";
+    field public static final java.lang.String EXTRA_QUIET_MODE = "android.intent.extra.QUIET_MODE";
     field public static final java.lang.String EXTRA_REFERRER = "android.intent.extra.REFERRER";
     field public static final java.lang.String EXTRA_REFERRER_NAME = "android.intent.extra.REFERRER_NAME";
     field public static final java.lang.String EXTRA_REMOTE_INTENT_TOKEN = "android.intent.extra.remote_intent_token";
@@ -9092,8 +9101,10 @@
     field public java.lang.String backupAgentName;
     field public java.lang.String className;
     field public int compatibleWidthLimitDp;
+    field public java.lang.String credentialEncryptedDataDir;
     field public java.lang.String dataDir;
     field public int descriptionRes;
+    field public java.lang.String deviceEncryptedDataDir;
     field public boolean enabled;
     field public int flags;
     field public int largestWidthLimitDp;
@@ -9415,6 +9426,8 @@
     method public abstract int getComponentEnabledSetting(android.content.ComponentName);
     method public abstract android.graphics.drawable.Drawable getDefaultActivityIcon();
     method public abstract android.graphics.drawable.Drawable getDrawable(java.lang.String, int, android.content.pm.ApplicationInfo);
+    method public abstract byte[] getEphemeralCookie();
+    method public abstract int getEphemeralCookieMaxSizeBytes();
     method public abstract java.util.List<android.content.pm.ApplicationInfo> getInstalledApplications(int);
     method public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int);
     method public abstract java.lang.String getInstallerPackageName(java.lang.String);
@@ -9446,6 +9459,7 @@
     method public abstract java.lang.CharSequence getUserBadgedLabel(java.lang.CharSequence, android.os.UserHandle);
     method public abstract android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
     method public abstract boolean hasSystemFeature(java.lang.String);
+    method public abstract boolean isEphemeralApplication();
     method public abstract boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
     method public abstract boolean isSafeMode();
     method public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
@@ -9463,6 +9477,7 @@
     method public abstract android.content.pm.ResolveInfo resolveService(android.content.Intent, int);
     method public abstract void setApplicationEnabledSetting(java.lang.String, int, int);
     method public abstract void setComponentEnabledSetting(android.content.ComponentName, int, int);
+    method public abstract boolean setEphemeralCookie(byte[]);
     method public abstract void setInstallerPackageName(java.lang.String, java.lang.String);
     method public abstract void verifyPendingInstall(int, int);
     field public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0; // 0x0
@@ -11527,6 +11542,7 @@
     field public static final int PRIVATE = 34; // 0x22
     field public static final int RAW10 = 37; // 0x25
     field public static final int RAW12 = 38; // 0x26
+    field public static final int RAW_PRIVATE = 36; // 0x24
     field public static final int RAW_SENSOR = 32; // 0x20
     field public static final int RGB_565 = 4; // 0x4
     field public static final int UNKNOWN = 0; // 0x0
@@ -20287,6 +20303,8 @@
     field public static final java.lang.String MIMETYPE_TEXT_CEA_608 = "text/cea-608";
     field public static final java.lang.String MIMETYPE_TEXT_VTT = "text/vtt";
     field public static final java.lang.String MIMETYPE_VIDEO_AVC = "video/avc";
+    field public static final java.lang.String MIMETYPE_VIDEO_DOLBY_AVC = "video/dolby-avc";
+    field public static final java.lang.String MIMETYPE_VIDEO_DOLBY_HEVC = "video/dolby-hevc";
     field public static final java.lang.String MIMETYPE_VIDEO_H263 = "video/3gpp";
     field public static final java.lang.String MIMETYPE_VIDEO_HEVC = "video/hevc";
     field public static final java.lang.String MIMETYPE_VIDEO_MPEG2 = "video/mpeg2";
@@ -20718,6 +20736,7 @@
   public static class MediaRouter.RouteInfo {
     method public android.media.MediaRouter.RouteCategory getCategory();
     method public java.lang.CharSequence getDescription();
+    method public int getDeviceType();
     method public android.media.MediaRouter.RouteGroup getGroup();
     method public android.graphics.drawable.Drawable getIconDrawable();
     method public java.lang.CharSequence getName();
@@ -20736,6 +20755,10 @@
     method public void requestSetVolume(int);
     method public void requestUpdateVolume(int);
     method public void setTag(java.lang.Object);
+    field public static final int DEVICE_TYPE_BLUETOOTH = 3; // 0x3
+    field public static final int DEVICE_TYPE_SPEAKER = 2; // 0x2
+    field public static final int DEVICE_TYPE_TV = 1; // 0x1
+    field public static final int DEVICE_TYPE_UNKNOWN = 0; // 0x0
     field public static final int PLAYBACK_TYPE_LOCAL = 0; // 0x0
     field public static final int PLAYBACK_TYPE_REMOTE = 1; // 0x1
     field public static final int PLAYBACK_VOLUME_FIXED = 0; // 0x0
@@ -28073,12 +28096,17 @@
     method public android.os.Bundle getUserRestrictions();
     method public android.os.Bundle getUserRestrictions(android.os.UserHandle);
     method public boolean hasUserRestriction(java.lang.String);
+    method public boolean isQuietModeEnabled(android.os.UserHandle);
     method public boolean isSystemUser();
     method public boolean isUserAGoat();
     method public boolean isUserRunning(android.os.UserHandle);
-    method public boolean isUserRunningAndLocked(android.os.UserHandle);
-    method public boolean isUserRunningAndUnlocked(android.os.UserHandle);
+    method public deprecated boolean isUserRunningAndLocked();
+    method public deprecated boolean isUserRunningAndLocked(android.os.UserHandle);
+    method public deprecated boolean isUserRunningAndUnlocked();
+    method public deprecated boolean isUserRunningAndUnlocked(android.os.UserHandle);
     method public boolean isUserRunningOrStopping(android.os.UserHandle);
+    method public boolean isUserUnlocked();
+    method public boolean isUserUnlocked(android.os.UserHandle);
     method public deprecated boolean setRestrictionsChallenge(java.lang.String);
     method public deprecated void setUserRestriction(java.lang.String, boolean);
     method public deprecated void setUserRestrictions(android.os.Bundle);
@@ -28464,6 +28492,7 @@
     method public android.preference.PreferenceScreen createPreferenceScreen(android.content.Context);
     method public android.preference.Preference findPreference(java.lang.CharSequence);
     method public static android.content.SharedPreferences getDefaultSharedPreferences(android.content.Context);
+    method public static java.lang.String getDefaultSharedPreferencesName(android.content.Context);
     method public android.content.SharedPreferences getSharedPreferences();
     method public int getSharedPreferencesMode();
     method public java.lang.String getSharedPreferencesName();
@@ -29678,6 +29707,7 @@
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/email_v2";
     field public static final android.net.Uri CONTENT_URI;
     field public static final java.lang.String DISPLAY_NAME = "data4";
+    field public static final android.net.Uri ENTERPRISE_CONTENT_FILTER_URI;
     field public static final android.net.Uri ENTERPRISE_CONTENT_LOOKUP_URI;
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
     field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
@@ -35199,6 +35229,7 @@
     field public static final java.lang.String KEY_VOICEMAIL_NOTIFICATION_PERSISTENT_BOOL = "voicemail_notification_persistent_bool";
     field public static final java.lang.String KEY_VOICE_PRIVACY_DISABLE_UI_BOOL = "voice_privacy_disable_ui_bool";
     field public static final java.lang.String KEY_VOLTE_REPLACEMENT_RAT_INT = "volte_replacement_rat_int";
+    field public static final java.lang.String KEY_VVM_CELLULAR_DATA_REQUIRED_BOOLEAN = "vvm_cellular_data_required";
     field public static final java.lang.String KEY_VVM_DESTINATION_NUMBER_STRING = "vvm_destination_number_string";
     field public static final java.lang.String KEY_VVM_PORT_NUMBER_INT = "vvm_port_number_int";
     field public static final java.lang.String KEY_VVM_TYPE_STRING = "vvm_type_string";
@@ -36229,6 +36260,7 @@
     method public int checkUriPermission(android.net.Uri, java.lang.String, java.lang.String, int, int, int);
     method public void clearWallpaper();
     method public android.content.Context createConfigurationContext(android.content.res.Configuration);
+    method public android.content.Context createDeviceEncryptedStorageContext();
     method public android.content.Context createDisplayContext(android.view.Display);
     method public android.content.Context createPackageContext(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
     method public java.lang.String[] databaseList();
@@ -36250,7 +36282,6 @@
     method public java.io.File getCodeCacheDir();
     method public android.content.ContentResolver getContentResolver();
     method public java.io.File getDatabasePath(java.lang.String);
-    method public java.io.File getDeviceEncryptedFilesDir();
     method public java.io.File getDir(java.lang.String, int);
     method public java.io.File getExternalCacheDir();
     method public java.io.File[] getExternalCacheDirs();
@@ -36270,6 +36301,7 @@
     method public android.content.res.Resources getResources();
     method public android.content.SharedPreferences getSharedPreferences(java.lang.String, int);
     method public android.content.SharedPreferences getSharedPreferences(java.io.File, int);
+    method public java.io.File getSharedPreferencesPath(java.lang.String);
     method public java.lang.Object getSystemService(java.lang.String);
     method public java.lang.String getSystemServiceName(java.lang.Class<?>);
     method public android.content.res.Resources.Theme getTheme();
@@ -36277,6 +36309,7 @@
     method public int getWallpaperDesiredMinimumHeight();
     method public int getWallpaperDesiredMinimumWidth();
     method public void grantUriPermission(java.lang.String, android.net.Uri, int);
+    method public boolean isDeviceEncryptedStorage();
     method public java.io.FileInputStream openFileInput(java.lang.String) throws java.io.FileNotFoundException;
     method public java.io.FileOutputStream openFileOutput(java.lang.String, int) throws java.io.FileNotFoundException;
     method public android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase.CursorFactory);
@@ -36400,6 +36433,8 @@
     method public android.graphics.drawable.Drawable getDefaultActivityIcon();
     method public java.lang.String getDefaultBrowserPackageName(int);
     method public android.graphics.drawable.Drawable getDrawable(java.lang.String, int, android.content.pm.ApplicationInfo);
+    method public byte[] getEphemeralCookie();
+    method public int getEphemeralCookieMaxSizeBytes();
     method public java.util.List<android.content.pm.ApplicationInfo> getInstalledApplications(int);
     method public java.util.List<android.content.pm.PackageInfo> getInstalledPackages(int);
     method public java.lang.String getInstallerPackageName(java.lang.String);
@@ -36430,6 +36465,7 @@
     method public java.lang.CharSequence getUserBadgedLabel(java.lang.CharSequence, android.os.UserHandle);
     method public android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
     method public boolean hasSystemFeature(java.lang.String);
+    method public boolean isEphemeralApplication();
     method public boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
     method public boolean isSafeMode();
     method public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
@@ -36448,6 +36484,7 @@
     method public void setApplicationEnabledSetting(java.lang.String, int, int);
     method public void setComponentEnabledSetting(android.content.ComponentName, int, int);
     method public boolean setDefaultBrowserPackageName(java.lang.String, int);
+    method public boolean setEphemeralCookie(byte[]);
     method public void setInstallerPackageName(java.lang.String, java.lang.String);
     method public void verifyPendingInstall(int, int);
   }
@@ -38674,9 +38711,9 @@
     method public int describeContents();
     method public static android.util.LocaleList forLanguageTags(java.lang.String);
     method public java.util.Locale get(int);
-    method public java.util.Locale getBestMatch(java.lang.String[]);
     method public static android.util.LocaleList getDefault();
     method public static android.util.LocaleList getEmptyLocaleList();
+    method public java.util.Locale getFirstMatch(java.lang.String[]);
     method public java.util.Locale getPrimary();
     method public boolean isEmpty();
     method public int size();
@@ -40218,6 +40255,7 @@
     field public static final int AXIS_RX = 12; // 0xc
     field public static final int AXIS_RY = 13; // 0xd
     field public static final int AXIS_RZ = 14; // 0xe
+    field public static final int AXIS_SCROLL = 26; // 0x1a
     field public static final int AXIS_SIZE = 3; // 0x3
     field public static final int AXIS_THROTTLE = 19; // 0x13
     field public static final int AXIS_TILT = 25; // 0x19
@@ -40526,7 +40564,6 @@
     method public android.view.accessibility.AccessibilityNodeInfo createAccessibilityNodeInfo();
     method public void createContextMenu(android.view.ContextMenu);
     method public void destroyDrawingCache();
-    method public final boolean didLayoutParamsChange();
     method public android.view.WindowInsets dispatchApplyWindowInsets(android.view.WindowInsets);
     method public void dispatchConfigurationChanged(android.content.res.Configuration);
     method public void dispatchDisplayHint(int);
@@ -40752,7 +40789,6 @@
     method public boolean isOpaque();
     method protected boolean isPaddingOffsetRequired();
     method public boolean isPaddingRelative();
-    method public final boolean isPartialLayoutRequested();
     method public boolean isPressed();
     method public boolean isSaveEnabled();
     method public boolean isSaveFromParentEnabled();
@@ -41364,7 +41400,6 @@
     method protected void dispatchThawSelfOnly(android.util.SparseArray<android.os.Parcelable>);
     method protected boolean drawChild(android.graphics.Canvas, android.view.View, long);
     method public void endViewTransition(android.view.View);
-    method public int findDependentLayoutAxes(android.view.View, int);
     method public android.view.View focusSearch(android.view.View, int);
     method public void focusableViewAvailable(android.view.View);
     method public boolean gatherTransparentRegion(android.graphics.Region);
@@ -41431,8 +41466,6 @@
     method public void requestChildFocus(android.view.View, android.view.View);
     method public boolean requestChildRectangleOnScreen(android.view.View, android.graphics.Rect, boolean);
     method public void requestDisallowInterceptTouchEvent(boolean);
-    method public void requestLayoutForChild(android.view.View);
-    method public void requestPartialLayoutForChild(android.view.View);
     method public boolean requestSendAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
     method public void requestTransparentRegion(android.view.View);
     method public void scheduleLayoutAnimation();
@@ -41547,7 +41580,6 @@
     method public abstract void childHasTransientStateChanged(android.view.View, boolean);
     method public abstract void clearChildFocus(android.view.View);
     method public abstract void createContextMenu(android.view.ContextMenu);
-    method public abstract int findDependentLayoutAxes(android.view.View, int);
     method public abstract android.view.View focusSearch(android.view.View, int);
     method public abstract void focusableViewAvailable(android.view.View);
     method public abstract boolean getChildVisibleRect(android.view.View, android.graphics.Rect, android.graphics.Point);
@@ -41577,16 +41609,12 @@
     method public abstract void requestDisallowInterceptTouchEvent(boolean);
     method public abstract void requestFitSystemWindows();
     method public abstract void requestLayout();
-    method public abstract void requestLayoutForChild(android.view.View);
     method public abstract boolean requestSendAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
     method public abstract void requestTransparentRegion(android.view.View);
     method public abstract boolean showContextMenuForChild(android.view.View);
     method public abstract boolean showContextMenuForChild(android.view.View, float, float);
     method public abstract android.view.ActionMode startActionModeForChild(android.view.View, android.view.ActionMode.Callback);
     method public abstract android.view.ActionMode startActionModeForChild(android.view.View, android.view.ActionMode.Callback, int);
-    field public static final int FLAG_LAYOUT_AXIS_ANY = 3; // 0x3
-    field public static final int FLAG_LAYOUT_AXIS_HORIZONTAL = 1; // 0x1
-    field public static final int FLAG_LAYOUT_AXIS_VERTICAL = 2; // 0x2
   }
 
   public class ViewPropertyAnimator {
@@ -41817,8 +41845,7 @@
     method public abstract void setContentView(int);
     method public abstract void setContentView(android.view.View);
     method public abstract void setContentView(android.view.View, android.view.ViewGroup.LayoutParams);
-    method public abstract void setDecorView(android.view.View);
-    method public abstract void setDecorView(int);
+    method public abstract void setDecorCaptionShade(int);
     method protected void setDefaultWindowFormat(int);
     method public void setDimAmount(float);
     method public void setElevation(float);
@@ -41839,6 +41866,8 @@
     method public void setMediaController(android.media.session.MediaController);
     method public abstract void setNavigationBarColor(int);
     method public void setReenterTransition(android.transition.Transition);
+    method public abstract void setResizingCaptionDrawable(android.graphics.drawable.Drawable);
+    method public final void setRestrictedCaptionAreaListener(android.view.Window.RestrictedCaptionAreaListener);
     method public void setReturnTransition(android.transition.Transition);
     method public void setSharedElementEnterTransition(android.transition.Transition);
     method public void setSharedElementExitTransition(android.transition.Transition);
@@ -41867,6 +41896,9 @@
     method public abstract void takeKeyEvents(boolean);
     method public abstract void takeSurface(android.view.SurfaceHolder.Callback2);
     method public abstract void togglePanel(int, android.view.KeyEvent);
+    field public static final int DECOR_CAPTION_SHADE_AUTO = 0; // 0x0
+    field public static final int DECOR_CAPTION_SHADE_DARK = 2; // 0x2
+    field public static final int DECOR_CAPTION_SHADE_LIGHT = 1; // 0x1
     field protected static final deprecated int DEFAULT_FEATURES = 65; // 0x41
     field public static final int FEATURE_ACTION_BAR = 8; // 0x8
     field public static final int FEATURE_ACTION_BAR_OVERLAY = 9; // 0x9
@@ -41921,6 +41953,10 @@
     method public abstract android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback, int);
   }
 
+  public static abstract interface Window.RestrictedCaptionAreaListener {
+    method public abstract void onRestrictedCaptionAreaChanged(android.graphics.Rect);
+  }
+
   public final class WindowAnimationFrameStats extends android.view.FrameStats implements android.os.Parcelable {
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
@@ -43185,7 +43221,8 @@
     method public java.lang.String getExtraValue();
     method public java.lang.String getExtraValueOf(java.lang.String);
     method public int getIconResId();
-    method public java.lang.String getLocale();
+    method public java.lang.String getLanguageTag();
+    method public deprecated java.lang.String getLocale();
     method public java.lang.String getMode();
     method public int getNameResId();
     method public boolean isAsciiCapable();
@@ -43200,6 +43237,7 @@
     method public android.view.inputmethod.InputMethodSubtype build();
     method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setIsAsciiCapable(boolean);
     method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setIsAuxiliary(boolean);
+    method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setLanguageTag(java.lang.String);
     method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setOverridesImplicitlyEnabledSubtype(boolean);
     method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setSubtypeExtraValue(java.lang.String);
     method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setSubtypeIconResId(int);
@@ -43257,13 +43295,14 @@
   }
 
   public final class SpellCheckerSubtype implements android.os.Parcelable {
-    ctor public SpellCheckerSubtype(int, java.lang.String, java.lang.String);
+    ctor public deprecated SpellCheckerSubtype(int, java.lang.String, java.lang.String);
     method public boolean containsExtraValueKey(java.lang.String);
     method public int describeContents();
     method public java.lang.CharSequence getDisplayName(android.content.Context, java.lang.String, android.content.pm.ApplicationInfo);
     method public java.lang.String getExtraValue();
     method public java.lang.String getExtraValueOf(java.lang.String);
-    method public java.lang.String getLocale();
+    method public java.lang.String getLanguageTag();
+    method public deprecated java.lang.String getLocale();
     method public int getNameResId();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.view.textservice.SpellCheckerSubtype> CREATOR;
@@ -49912,7 +49951,6 @@
   public abstract class Reference {
     method public void clear();
     method public boolean enqueue();
-    method public final synchronized boolean enqueueInternal();
     method public T get();
     method public boolean isEnqueued();
   }
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 2ad63b5..4f7a109 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -142,6 +142,7 @@
                 "       am clear-debug-app\n" +
                 "       am set-watch-heap <PROCESS> <MEM-LIMIT>\n" +
                 "       am clear-watch-heap\n" +
+                "       am bug-report [--progress]\n" +
                 "       am monitor [--gdb <port>]\n" +
                 "       am hang [--allow-restart]\n" +
                 "       am restart\n" +
@@ -258,8 +259,9 @@
                 "\n" +
                 "am clear-watch-heap: clear the previously set-watch-heap.\n" +
                 "\n" +
-                "am bug-report: request bug report generation; will launch UI\n" +
-                "    when done to select where it should be delivered.\n" +
+                "am bug-report: request bug report generation; will launch a notification\n" +
+                "    when done to select where it should be delivered. Options are: \n" +
+                "   --progress: will launch a notification right away to show its progress.\n" +
                 "\n" +
                 "am monitor: start monitoring for crashes or ANRs.\n" +
                 "    --gdb: start gdbserv on the given port at crash/ANR\n" +
@@ -1072,7 +1074,17 @@
     }
 
     private void runBugReport() throws Exception {
-        mAm.requestBugReport();
+        String opt;
+        boolean progress = false;
+        while ((opt=nextOption()) != null) {
+            if (opt.equals("--progress")) {
+                progress = true;
+            } else {
+                System.err.println("Error: Unknown option: " + opt);
+                return;
+            }
+        }
+        mAm.requestBugReport(progress);
         System.out.println("Your lovely bug report is being created; please be patient.");
     }
 
diff --git a/cmds/dpm/src/com/android/commands/dpm/Dpm.java b/cmds/dpm/src/com/android/commands/dpm/Dpm.java
index ea53009..6dc3cd1 100644
--- a/cmds/dpm/src/com/android/commands/dpm/Dpm.java
+++ b/cmds/dpm/src/com/android/commands/dpm/Dpm.java
@@ -16,6 +16,8 @@
 
 package com.android.commands.dpm;
 
+import android.app.ActivityManagerNative;
+import android.app.IActivityManager;
 import android.app.admin.IDevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -51,19 +53,21 @@
     public void onShowUsage(PrintStream out) {
         out.println(
                 "usage: dpm [subcommand] [options]\n" +
-                "usage: dpm set-active-admin [ --user <USER_ID> ] <COMPONENT>\n" +
+                "usage: dpm set-active-admin [ --user <USER_ID> | current ] <COMPONENT>\n" +
                 // STOPSHIP Finalize it
-                "usage: dpm set-device-owner [ --user <USER_ID> *EXPERIMENTAL* ] [ --name <NAME> ] <COMPONENT>\n" +
-                "usage: dpm set-profile-owner [ --user <USER_ID> ] [ --name <NAME> ] <COMPONENT>\n" +
+                "usage: dpm set-device-owner [ --user <USER_ID> | current *EXPERIMENTAL* ] " +
+                "[ --name <NAME> ] <COMPONENT>\n" +
+                "usage: dpm set-profile-owner [ --user <USER_ID> | current ] [ --name <NAME> ] " +
+                "<COMPONENT>\n" +
                 "\n" +
                 "dpm set-active-admin: Sets the given component as active admin" +
                 " for an existing user.\n" +
                 "\n" +
-                "dpm set-device-owner: Sets the given component as active admin, and its\n" +
-                "  package as device owner.\n" +
+                "dpm set-device-owner: Sets the given component as active admin, and its" +
+                " package as device owner.\n" +
                 "\n" +
                 "dpm set-profile-owner: Sets the given component as active admin and profile" +
-                "  owner for an existing user.\n");
+                " owner for an existing user.\n");
     }
 
     @Override
@@ -91,11 +95,24 @@
         }
     }
 
-    private void parseArgs(boolean canHaveUser, boolean canHaveName) {
+    private void parseArgs(boolean canHaveName) {
         String opt;
         while ((opt = nextOption()) != null) {
-            if (canHaveUser && "--user".equals(opt)) {
-                mUserId = parseInt(nextArgRequired());
+            if ("--user".equals(opt)) {
+                String arg = nextArgRequired();
+                if ("current".equals(arg) || "cur".equals(arg)) {
+                    mUserId = UserHandle.USER_CURRENT;
+                } else {
+                    mUserId = parseInt(arg);
+                }
+                if (mUserId == UserHandle.USER_CURRENT) {
+                    IActivityManager activityManager = ActivityManagerNative.getDefault();
+                    try {
+                        mUserId = activityManager.getCurrentUser().id;
+                    } catch (RemoteException e) {
+                        e.rethrowAsRuntimeException();
+                    }
+                }
             } else if (canHaveName && "--name".equals(opt)) {
                 mName = nextArgRequired();
             } else {
@@ -106,14 +123,14 @@
     }
 
     private void runSetActiveAdmin() throws RemoteException {
-        parseArgs(/*canHaveUser=*/ true, /*canHaveName=*/ false);
+        parseArgs(/*canHaveName=*/ false);
         mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId);
 
         System.out.println("Success: Active admin set to component " + mComponent.toShortString());
     }
 
     private void runSetDeviceOwner() throws RemoteException {
-        parseArgs(/*canHaveUser=*/ true, /*canHaveName=*/ true);
+        parseArgs(/*canHaveName=*/ true);
         mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId);
 
         try {
@@ -131,7 +148,7 @@
     }
 
     private void runSetProfileOwner() throws RemoteException {
-        parseArgs(/*canHaveUser=*/ true, /*canHaveName=*/ true);
+        parseArgs(/*canHaveName=*/ true);
         mDevicePolicyManager.setActiveAdmin(mComponent, true /*refreshing*/, mUserId);
 
         try {
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 544fd6a..ad1b3b5 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -16,11 +16,11 @@
 
 package com.android.commands.pm;
 
-import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
-import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
+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 android.accounts.IAccountManager;
 import android.app.ActivityManager;
@@ -139,19 +139,19 @@
         }
 
         if ("install-create".equals(op)) {
-            return runInstallSession();
+            return runInstallCreate();
         }
 
         if ("install-write".equals(op)) {
-            return runInstallSession();
+            return runInstallWrite();
         }
 
         if ("install-commit".equals(op)) {
-            return runInstallSession();
+            return runInstallCommit();
         }
 
         if ("install-abandon".equals(op) || "install-destroy".equals(op)) {
-            return runInstallSession();
+            return runInstallAbandon();
         }
 
         if ("set-installer".equals(op)) {
@@ -346,21 +346,203 @@
         throw new IllegalArgumentException("ABI " + abi + " not supported on this device");
     }
 
-    private void writeSessionFile(int sessionId, String path, long sizeBytes) throws RemoteException {
+    /*
+     * Keep this around to support existing users of the "pm install" command that may not be
+     * able to be updated [or, at least informed the API has changed] such as ddmlib.
+     *
+     * Moving the implementation of "pm install" to "cmd package install" changes the executing
+     * context. Instead of being a stand alone process, "cmd package install" runs in the
+     * system_server process. Due to SELinux rules, system_server cannot access many directories;
+     * one of which being the package install staging directory [/data/local/tmp].
+     *
+     * The use of "adb install" or "cmd package install" over "pm install" is highly encouraged.
+     */
+    private int runInstall() throws RemoteException {
+        final InstallParams params = makeInstallParams();
+        final int sessionId = doCreateSession(params.sessionParams,
+                params.installerPackageName, params.userId);
+
+        try {
+            final String inPath = nextArg();
+            if (inPath == null && params.sessionParams.sizeBytes == 0) {
+                System.err.println("Error: must either specify a package size or an APK file");
+                return 1;
+            }
+            if (doWriteSession(sessionId, inPath, params.sessionParams.sizeBytes, "base.apk",
+                    false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) {
+                return 1;
+            }
+            if (doCommitSession(sessionId, false /*logSuccess*/)
+                    != PackageInstaller.STATUS_SUCCESS) {
+                return 1;
+            }
+            return 0;
+        } finally {
+            try {
+                mInstaller.abandonSession(sessionId);
+            } catch (Exception ignore) {
+            }
+        }
+    }
+
+    private int runInstallAbandon() throws RemoteException {
+        final int sessionId = Integer.parseInt(nextArg());
+        return doAbandonSession(sessionId, true /*logSuccess*/);
+    }
+
+    private int runInstallCommit() throws RemoteException {
+        final int sessionId = Integer.parseInt(nextArg());
+        return doCommitSession(sessionId, true /*logSuccess*/);
+    }
+
+    private int runInstallCreate() throws RemoteException {
+        final InstallParams installParams = makeInstallParams();
+        final int sessionId = doCreateSession(installParams.sessionParams,
+                installParams.installerPackageName, installParams.userId);
+
+        // NOTE: adb depends on parsing this string
+        System.out.println("Success: created install session [" + sessionId + "]");
+        return PackageInstaller.STATUS_SUCCESS;
+    }
+
+    private int runInstallWrite() throws RemoteException {
+        long sizeBytes = -1;
+
+        String opt;
+        while ((opt = nextOption()) != null) {
+            if (opt.equals("-S")) {
+                sizeBytes = Long.parseLong(nextArg());
+            } else {
+                throw new IllegalArgumentException("Unknown option: " + opt);
+            }
+        }
+
+        final int sessionId = Integer.parseInt(nextArg());
+        final String splitName = nextArg();
+        final String path = nextArg();
+        return doWriteSession(sessionId, path, sizeBytes, splitName, true /*logSuccess*/);
+    }
+
+    private static class InstallParams {
+        SessionParams sessionParams;
+        String installerPackageName;
+        int userId = UserHandle.USER_ALL;
+    }
+
+    private InstallParams makeInstallParams() {
+        final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL);
+        final InstallParams params = new InstallParams();
+        params.sessionParams = sessionParams;
+        String opt;
+        while ((opt = nextOption()) != null) {
+            switch (opt) {
+                case "-l":
+                    sessionParams.installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
+                    break;
+                case "-r":
+                    sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
+                    break;
+                case "-i":
+                    params.installerPackageName = nextArg();
+                    if (params.installerPackageName == null) {
+                        throw new IllegalArgumentException("Missing installer package");
+                    }
+                    break;
+                case "-t":
+                    sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_TEST;
+                    break;
+                case "-s":
+                    sessionParams.installFlags |= PackageManager.INSTALL_EXTERNAL;
+                    break;
+                case "-f":
+                    sessionParams.installFlags |= PackageManager.INSTALL_INTERNAL;
+                    break;
+                case "-d":
+                    sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
+                    break;
+                case "-g":
+                    sessionParams.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
+                    break;
+                case "--originating-uri":
+                    sessionParams.originatingUri = Uri.parse(nextOptionData());
+                    break;
+                case "--referrer":
+                    sessionParams.referrerUri = Uri.parse(nextOptionData());
+                    break;
+                case "-p":
+                    sessionParams.mode = SessionParams.MODE_INHERIT_EXISTING;
+                    sessionParams.appPackageName = nextOptionData();
+                    if (sessionParams.appPackageName == null) {
+                        throw new IllegalArgumentException("Missing inherit package name");
+                    }
+                    break;
+                case "-S":
+                    sessionParams.setSize(Long.parseLong(nextOptionData()));
+                    break;
+                case "--abi":
+                    sessionParams.abiOverride = checkAbiArgument(nextOptionData());
+                    break;
+                case "--ephemeral":
+                    sessionParams.installFlags |= PackageManager.INSTALL_EPHEMERAL;
+                    break;
+                case "--user":
+                    params.userId = UserHandle.parseUserArg(nextOptionData());
+                    break;
+                case "--install-location":
+                    sessionParams.installLocation = Integer.parseInt(nextOptionData());
+                    break;
+                case "--force-uuid":
+                    sessionParams.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID;
+                    sessionParams.volumeUuid = nextOptionData();
+                    if ("internal".equals(sessionParams.volumeUuid)) {
+                        sessionParams.volumeUuid = null;
+                    }
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unknown option " + opt);
+            }
+        }
+        return params;
+    }
+
+    private int doCreateSession(SessionParams params, String installerPackageName, int userId)
+            throws RemoteException {
+        userId = translateUserId(userId, "runInstallCreate");
+        if (userId == UserHandle.USER_ALL) {
+            userId = UserHandle.USER_SYSTEM;
+            params.installFlags |= PackageManager.INSTALL_ALL_USERS;
+        }
+
+        final int sessionId = mInstaller.createSession(params, installerPackageName, userId);
+        return sessionId;
+    }
+
+    private int doWriteSession(int sessionId, String inPath, long sizeBytes, String splitName,
+            boolean logSuccess) throws RemoteException {
+        if ("-".equals(inPath)) {
+            inPath = null;
+        } else if (inPath != null) {
+            final File file = new File(inPath);
+            if (file.isFile()) {
+                sizeBytes = file.length();
+            }
+        }
+
         final SessionInfo info = mInstaller.getSessionInfo(sessionId);
 
         PackageInstaller.Session session = null;
         InputStream in = null;
         OutputStream out = null;
         try {
-            session = new PackageInstaller.Session(mInstaller.openSession(sessionId));
+            session = new PackageInstaller.Session(
+                    mInstaller.openSession(sessionId));
 
-            if (path == null) {
-                in = new SizedInputStream(System.in, sizeBytes);
+            if (inPath != null) {
+                in = new FileInputStream(inPath);
             } else {
-                in = new FileInputStream(path);
+                in = new SizedInputStream(System.in, sizeBytes);
             }
-            out = session.openWrite("base.apk", 0, sizeBytes);
+            out = session.openWrite(splitName, 0, sizeBytes);
 
             int total = 0;
             byte[] buffer = new byte[65536];
@@ -375,7 +557,14 @@
                 }
             }
             session.fsync(out);
-        } catch (IOException ignore) {
+
+            if (logSuccess) {
+                System.out.println("Success: streamed " + total + " bytes");
+            }
+            return PackageInstaller.STATUS_SUCCESS;
+        } catch (IOException e) {
+            System.err.println("Error: failed to write; " + e.getMessage());
+            return PackageInstaller.STATUS_FAILURE;
         } finally {
             IoUtils.closeQuietly(out);
             IoUtils.closeQuietly(in);
@@ -383,10 +572,11 @@
         }
     }
 
-    private int commitSessionFile(int sessionId) throws RemoteException {
+    private int doCommitSession(int sessionId, boolean logSuccess) throws RemoteException {
         PackageInstaller.Session session = null;
         try {
-            session = new PackageInstaller.Session(mInstaller.openSession(sessionId));
+            session = new PackageInstaller.Session(
+                    mInstaller.openSession(sessionId));
 
             final LocalIntentReceiver receiver = new LocalIntentReceiver();
             session.commit(receiver.getIntentSender());
@@ -395,10 +585,13 @@
             final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
                     PackageInstaller.STATUS_FAILURE);
             if (status == PackageInstaller.STATUS_SUCCESS) {
-                System.out.println("Success");
+                if (logSuccess) {
+                    System.out.println("Success");
+                }
             } else {
                 System.err.println("Failure ["
                         + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
+                System.err.println("Failure details: " + result.getExtras());
             }
             return status;
         } finally {
@@ -406,100 +599,18 @@
         }
     }
 
-    /*
-     * Keep this around to support existing users of the "pm install" command that may not be
-     * able to be updated [or, at least informed the API has changed] such as ddmlib.
-     *
-     * Moving the implementation of "pm install" to "cmd package install" changes the executing
-     * context. Instead of being a stand alone process, "cmd package install" runs in the
-     * system_server process. Due to SELinux rules, system_server cannot access many directories;
-     * one of which being the package install staging directory [/data/local/tmp].
-     *
-     * The use of "adb install" or "cmd package install" over "pm install" is highly encouraged.
-     */
-    private int runInstall() throws RemoteException {
-        int userId = UserHandle.USER_ALL;
-        String installerPackageName = null;
-
-        final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);
-
-        String opt;
-        while ((opt = nextOption()) != null) {
-            if (opt.equals("-l")) {
-                params.installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
-            } else if (opt.equals("-r")) {
-                params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
-            } else if (opt.equals("-i")) {
-                installerPackageName = nextArg();
-                if (installerPackageName == null) {
-                    throw new IllegalArgumentException("Missing installer package");
-                }
-            } else if (opt.equals("-t")) {
-                params.installFlags |= PackageManager.INSTALL_ALLOW_TEST;
-            } else if (opt.equals("-s")) {
-                params.installFlags |= PackageManager.INSTALL_EXTERNAL;
-            } else if (opt.equals("-f")) {
-                params.installFlags |= PackageManager.INSTALL_INTERNAL;
-            } else if (opt.equals("-d")) {
-                params.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
-            } else if (opt.equals("-g")) {
-                params.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
-            } else if (opt.equals("--originating-uri")) {
-                params.originatingUri = Uri.parse(nextOptionData());
-            } else if (opt.equals("--referrer")) {
-                params.referrerUri = Uri.parse(nextOptionData());
-            } else if (opt.equals("-p")) {
-                params.mode = SessionParams.MODE_INHERIT_EXISTING;
-                params.appPackageName = nextOptionData();
-                if (params.appPackageName == null) {
-                    throw new IllegalArgumentException("Missing inherit package name");
-                }
-            } else if (opt.equals("-S")) {
-                params.setSize(Long.parseLong(nextOptionData()));
-            } else if (opt.equals("--abi")) {
-                params.abiOverride = checkAbiArgument(nextOptionData());
-            } else if (opt.equals("--ephemeral")) {
-                params.installFlags |= PackageManager.INSTALL_EPHEMERAL;
-            } else if (opt.equals("--user")) {
-                userId = Integer.parseInt(nextOptionData());
-            } else if (opt.equals("--install-location")) {
-                params.installLocation = Integer.parseInt(nextOptionData());
-            } else if (opt.equals("--force-uuid")) {
-                params.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID;
-                params.volumeUuid = nextOptionData();
-                if ("internal".equals(params.volumeUuid)) {
-                    params.volumeUuid = null;
-                }
-            } else {
-                throw new IllegalArgumentException("Unknown option " + opt);
+    private int doAbandonSession(int sessionId, boolean logSuccess) throws RemoteException {
+        PackageInstaller.Session session = null;
+        try {
+            session = new PackageInstaller.Session(mInstaller.openSession(sessionId));
+            session.abandon();
+            if (logSuccess) {
+                System.out.println("Success");
             }
+            return PackageInstaller.STATUS_SUCCESS;
+        } finally {
+            IoUtils.closeQuietly(session);
         }
-
-        userId = translateUserId(userId, "runInstallCreate");
-        if (userId == UserHandle.USER_ALL) {
-            userId = UserHandle.USER_SYSTEM;
-            params.installFlags |= PackageManager.INSTALL_ALL_USERS;
-        }
-
-        long sizeBytes = params.sizeBytes;
-        String path = nextArg();
-        if ("-".equals(path)) {
-            path = null;
-        } else if (path != null) {
-            final File file = new File(path);
-            if (file.isFile()) {
-                sizeBytes = file.length();
-            }
-        }
-
-        final int sessionId = mInstaller.createSession(params, installerPackageName, userId);
-
-        writeSessionFile(sessionId, path, sizeBytes);
-        return commitSessionFile(sessionId);
-    }
-
-    private int runInstallSession() {
-        return runShellCommand("package", mArgs);
     }
 
     /**
@@ -798,6 +909,10 @@
                 flags |= UserInfo.FLAG_MANAGED_PROFILE;
             } else if ("--restricted".equals(opt)) {
                 flags |= UserInfo.FLAG_RESTRICTED;
+            } else if ("--ephemeral".equals(opt)) {
+                flags |= UserInfo.FLAG_EPHEMERAL;
+            } else if ("--guest".equals(opt)) {
+                flags |= UserInfo.FLAG_GUEST;
             } else {
                 System.err.println("Error: unknown option " + opt);
                 return showUsage();
@@ -1356,7 +1471,7 @@
         System.err.println("       pm get-install-location");
         System.err.println("       pm set-permission-enforced PERMISSION [true|false]");
         System.err.println("       pm trim-caches DESIRED_FREE_SPACE [internal|UUID]");
-        System.err.println("       pm create-user [--profileOf USER_ID] [--managed] [--restricted] USER_NAME");
+        System.err.println("       pm create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral] [--guest] USER_NAME");
         System.err.println("       pm remove-user USER_ID");
         System.err.println("       pm get-max-users");
         System.err.println("");
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index b11a12f..81fe23c 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -559,6 +559,14 @@
         public static boolean isAlwaysOnTop(int stackId) {
             return stackId == PINNED_STACK_ID;
         }
+
+        /**
+         * Returns true if the application windows in this stack should be displayed above all
+         * other application windows, including during the animation.
+         */
+        public static boolean shouldIncreaseApplicationWindowLayer(int stackId) {
+            return stackId == PINNED_STACK_ID || stackId == DOCKED_STACK_ID;
+        }
     }
 
     /**
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index ee2efcc..4cb2619 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2228,7 +2228,8 @@
 
         case REQUEST_BUG_REPORT_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
-            requestBugReport();
+            boolean progress = data.readInt() != 0;
+            requestBugReport(progress);
             reply.writeNoException();
             return true;
         }
@@ -2717,10 +2718,10 @@
             reply.writeNoException();
             return true;
         }
-        case REMOVE_STACK_TRANSACTION: {
+        case MOVE_TASKS_TO_FULLSCREEN_STACK_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             final int stackId = data.readInt();
-            removeStack(stackId);
+            moveTasksToFullscreenStack(stackId);
             reply.writeNoException();
             return true;
         }
@@ -5616,10 +5617,11 @@
         reply.recycle();
     }
 
-    public void requestBugReport() throws RemoteException {
+    public void requestBugReport(boolean progress) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(progress ? 1 : 0);
         mRemote.transact(REQUEST_BUG_REPORT_TRANSACTION, data, reply, 0);
         reply.readException();
         data.recycle();
@@ -6356,12 +6358,12 @@
     }
 
     @Override
-    public void removeStack(int stackId) throws RemoteException {
+    public void moveTasksToFullscreenStack(int fromStackId) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(stackId);
-        mRemote.transact(REMOVE_STACK_TRANSACTION, data, reply, 0);
+        data.writeInt(fromStackId);
+        mRemote.transact(MOVE_TASKS_TO_FULLSCREEN_STACK_TRANSACTION, data, reply, 0);
         reply.readException();
         data.recycle();
         reply.recycle();
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index e500e15..460e68c 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -30,6 +30,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ComponentInfo;
 import android.content.pm.ContainerEncryptionParams;
+import android.content.pm.EphemeralApplicationInfo;
 import android.content.pm.FeatureInfo;
 import android.content.pm.IOnPermissionsChangeListener;
 import android.content.pm.IPackageDataObserver;
@@ -85,9 +86,11 @@
 import com.android.internal.os.SomeArgs;
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.UserIcons;
+import libcore.util.EmptyArray;
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -98,6 +101,8 @@
     private static final String TAG = "ApplicationPackageManager";
     private final static boolean DEBUG_ICONS = false;
 
+    private static final int DEFAULT_EPHEMERAL_COOKIE_MAX_SIZE_BYTES = 16384; // 16KB
+
     // Default flags to use with PackageManager when no flags are given.
     private final static int sDefaultFlags = PackageManager.GET_SHARED_LIBRARY_FILES;
 
@@ -626,6 +631,80 @@
         }
     }
 
+    /** @hide */
+    @SuppressWarnings("unchecked")
+    @Override
+    public List<EphemeralApplicationInfo> getEphemeralApplications() {
+        try {
+            ParceledListSlice<EphemeralApplicationInfo> slice =
+                    mPM.getEphemeralApplications(mContext.getUserId());
+            if (slice != null) {
+                return slice.getList();
+            }
+            return Collections.emptyList();
+        } catch (RemoteException e) {
+            throw new RuntimeException("Package manager has died", e);
+        }
+    }
+
+    /** @hide */
+    @Override
+    public Drawable getEphemeralApplicationIcon(String packageName) {
+        try {
+            Bitmap bitmap = mPM.getEphemeralApplicationIcon(
+                    packageName, mContext.getUserId());
+            if (bitmap != null) {
+                return new BitmapDrawable(null, bitmap);
+            }
+            return null;
+        } catch (RemoteException e) {
+            throw new RuntimeException("Package manager has died", e);
+        }
+    }
+
+    @Override
+    public boolean isEphemeralApplication() {
+        try {
+            return mPM.isEphemeralApplication(
+                    mContext.getPackageName(), mContext.getUserId());
+        } catch (RemoteException e) {
+            Log.e(TAG, "System server is dead", e);
+        }
+        return false;
+    }
+
+    @Override
+    public int getEphemeralCookieMaxSizeBytes() {
+        return Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.EPHEMERAL_COOKIE_MAX_SIZE_BYTES,
+                DEFAULT_EPHEMERAL_COOKIE_MAX_SIZE_BYTES);
+    }
+
+    @Override
+    public @NonNull byte[] getEphemeralCookie() {
+        try {
+            final byte[] cookie = mPM.getEphemeralApplicationCookie(
+                    mContext.getPackageName(), mContext.getUserId());
+            if (cookie != null) {
+                return cookie;
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "System server is dead", e);
+        }
+        return EmptyArray.BYTE;
+    }
+
+    @Override
+    public boolean setEphemeralCookie(@NonNull  byte[] cookie) {
+        try {
+            return mPM.setEphemeralApplicationCookie(
+                    mContext.getPackageName(), cookie, mContext.getUserId());
+        } catch (RemoteException e) {
+            Log.e(TAG, "System server is dead", e);
+        }
+        return false;
+    }
+
     @Override
     public ResolveInfo resolveActivity(Intent intent, int flags) {
         return resolveActivityAsUser(intent, flags, mContext.getUserId());
diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java
index 1f378da..175b979 100644
--- a/core/java/android/app/BroadcastOptions.java
+++ b/core/java/android/app/BroadcastOptions.java
@@ -17,6 +17,7 @@
 package android.app;
 
 import android.annotation.SystemApi;
+import android.os.Build;
 import android.os.Bundle;
 
 /**
@@ -28,15 +29,28 @@
 @SystemApi
 public class BroadcastOptions {
     private long mTemporaryAppWhitelistDuration;
+    private int mMinManifestReceiverApiLevel = 0;
+    private int mMaxManifestReceiverApiLevel = Build.VERSION_CODES.CUR_DEVELOPMENT;
 
     /**
      * How long to temporarily put an app on the power whitelist when executing this broadcast
      * to it.
-     * @hide
      */
-    public static final String KEY_TEMPORARY_APP_WHITELIST_DURATION
+    static final String KEY_TEMPORARY_APP_WHITELIST_DURATION
             = "android:broadcast.temporaryAppWhitelistDuration";
 
+    /**
+     * Corresponds to {@link #setMinManifestReceiverApiLevel}.
+     */
+    static final String KEY_MIN_MANIFEST_RECEIVER_API_LEVEL
+            = "android:broadcast.minManifestReceiverApiLevel";
+
+    /**
+     * Corresponds to {@link #setMaxManifestReceiverApiLevel}.
+     */
+    static final String KEY_MAX_MANIFEST_RECEIVER_API_LEVEL
+            = "android:broadcast.maxManifestReceiverApiLevel";
+
     public static BroadcastOptions makeBasic() {
         BroadcastOptions opts = new BroadcastOptions();
         return opts;
@@ -48,6 +62,9 @@
     /** @hide */
     public BroadcastOptions(Bundle opts) {
         mTemporaryAppWhitelistDuration = opts.getLong(KEY_TEMPORARY_APP_WHITELIST_DURATION);
+        mMinManifestReceiverApiLevel = opts.getInt(KEY_MIN_MANIFEST_RECEIVER_API_LEVEL, 0);
+        mMaxManifestReceiverApiLevel = opts.getInt(KEY_MAX_MANIFEST_RECEIVER_API_LEVEL,
+                Build.VERSION_CODES.CUR_DEVELOPMENT);
     }
 
     /**
@@ -68,10 +85,46 @@
     }
 
     /**
+     * Set the minimum target API level of receivers of the broadcast.  If an application
+     * is targeting an API level less than this, the broadcast will not be delivered to
+     * them.  This only applies to receivers declared in the app's AndroidManifest.xml.
+     * @hide
+     */
+    public void setMinManifestReceiverApiLevel(int apiLevel) {
+        mMinManifestReceiverApiLevel = apiLevel;
+    }
+
+    /**
+     * Return {@link #setMinManifestReceiverApiLevel}.
+     * @hide
+     */
+    public int getMinManifestReceiverApiLevel() {
+        return mMinManifestReceiverApiLevel;
+    }
+
+    /**
+     * Set the maximum target API level of receivers of the broadcast.  If an application
+     * is targeting an API level greater than this, the broadcast will not be delivered to
+     * them.  This only applies to receivers declared in the app's AndroidManifest.xml.
+     * @hide
+     */
+    public void setMaxManifestReceiverApiLevel(int apiLevel) {
+        mMaxManifestReceiverApiLevel = apiLevel;
+    }
+
+    /**
+     * Return {@link #setMaxManifestReceiverApiLevel}.
+     * @hide
+     */
+    public int getMaxManifestReceiverApiLevel() {
+        return mMaxManifestReceiverApiLevel;
+    }
+
+    /**
      * Returns the created options as a Bundle, which can be passed to
      * {@link android.content.Context#sendBroadcast(android.content.Intent)
      * Context.sendBroadcast(Intent)} and related methods.
-     * Note that the returned Bundle is still owned by the ActivityOptions
+     * Note that the returned Bundle is still owned by the BroadcastOptions
      * object; you must not modify it, but can supply it to the sendBroadcast
      * methods that take an options Bundle.
      */
@@ -80,6 +133,12 @@
         if (mTemporaryAppWhitelistDuration > 0) {
             b.putLong(KEY_TEMPORARY_APP_WHITELIST_DURATION, mTemporaryAppWhitelistDuration);
         }
+        if (mMinManifestReceiverApiLevel != 0) {
+            b.putInt(KEY_MIN_MANIFEST_RECEIVER_API_LEVEL, mMinManifestReceiverApiLevel);
+        }
+        if (mMaxManifestReceiverApiLevel != Build.VERSION_CODES.CUR_DEVELOPMENT) {
+            b.putInt(KEY_MAX_MANIFEST_RECEIVER_API_LEVEL, mMaxManifestReceiverApiLevel);
+        }
         return b.isEmpty() ? null : b;
     }
 }
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 23c4198..569ab11 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -61,6 +61,7 @@
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.storage.IMountService;
+import android.os.storage.StorageManager;
 import android.util.AndroidRuntimeException;
 import android.util.ArrayMap;
 import android.util.Log;
@@ -74,6 +75,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Objects;
 
 class ReceiverRestrictedContext extends ContextWrapper {
     ReceiverRestrictedContext(Context base) {
@@ -148,7 +150,7 @@
     private final Display mDisplay; // may be null if default display
     private final DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
 
-    private final boolean mRestricted;
+    private final int mFlags;
 
     private Context mOuterContext;
     private int mThemeResource = 0;
@@ -321,11 +323,6 @@
     }
 
     @Override
-    public File getSharedPrefsFile(String name) {
-        return makeFilename(getPreferencesDir(), name + ".xml");
-    }
-
-    @Override
     public SharedPreferences getSharedPreferences(String name, int mode) {
         // At least one application in the world actually passes in a null
         // name.  This happened to work because when we generated the file name
@@ -337,7 +334,7 @@
             }
         }
 
-        final File file = getSharedPrefsFile(name);
+        final File file = getSharedPreferencesPath(name);
         return getSharedPreferences(file, mode);
     }
 
@@ -448,22 +445,6 @@
     }
 
     @Override
-    public File getDeviceEncryptedFilesDir() {
-        if (mPackageInfo != null) {
-            return mPackageInfo.getDeviceEncryptedDataDirFile();
-        }
-        throw new RuntimeException("Not supported in system context");
-    }
-
-    @Override
-    public File getCredentialEncryptedFilesDir() {
-        if (mPackageInfo != null) {
-            return mPackageInfo.getCredentialEncryptedDataDirFile();
-        }
-        throw new RuntimeException("Not supported in system context");
-    }
-
-    @Override
     public File getNoBackupFilesDir() {
         synchronized (mSync) {
             if (mNoBackupFilesDir == null) {
@@ -571,6 +552,11 @@
     }
 
     @Override
+    public File getSharedPreferencesPath(String name) {
+        return makeFilename(getPreferencesDir(), name + ".xml");
+    }
+
+    @Override
     public String[] fileList() {
         final String[] list = getFilesDir().list();
         return (list != null) ? list : EMPTY_STRING_ARRAY;
@@ -1107,7 +1093,23 @@
             intent.prepareToLeaveProcess();
             ActivityManagerNative.getDefault().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, null,
-                Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, true, user.getIdentifier());
+                Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, true,
+                    user.getIdentifier());
+        } catch (RemoteException e) {
+            throw new RuntimeException("Failure from system", e);
+        }
+    }
+
+    @Override
+    @Deprecated
+    public void sendStickyBroadcastAsUser(Intent intent, UserHandle user, Bundle options) {
+        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
+        try {
+            intent.prepareToLeaveProcess();
+            ActivityManagerNative.getDefault().broadcastIntent(
+                mMainThread.getApplicationThread(), intent, resolvedType, null,
+                Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, options, false, true,
+                user.getIdentifier());
         } catch (RemoteException e) {
             throw new RuntimeException("Failure from system", e);
         }
@@ -1684,9 +1686,8 @@
         LoadedApk pi = mMainThread.getPackageInfo(application, mResources.getCompatibilityInfo(),
                 flags | CONTEXT_REGISTER_PACKAGE);
         if (pi != null) {
-            final boolean restricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
             ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken,
-                    new UserHandle(UserHandle.getUserId(application.uid)), restricted,
+                    new UserHandle(UserHandle.getUserId(application.uid)), flags,
                     mDisplay, null, Display.INVALID_DISPLAY);
             if (c.mResources != null) {
                 return c;
@@ -1707,17 +1708,16 @@
     @Override
     public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
             throws NameNotFoundException {
-        final boolean restricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
         if (packageName.equals("system") || packageName.equals("android")) {
             return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
-                    user, restricted, mDisplay, null, Display.INVALID_DISPLAY);
+                    user, flags, mDisplay, null, Display.INVALID_DISPLAY);
         }
 
         LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(),
                 flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier());
         if (pi != null) {
             ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken,
-                    user, restricted, mDisplay, null, Display.INVALID_DISPLAY);
+                    user, flags, mDisplay, null, Display.INVALID_DISPLAY);
             if (c.mResources != null) {
                 return c;
             }
@@ -1735,7 +1735,7 @@
         }
 
         return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
-                mUser, mRestricted, mDisplay, overrideConfiguration, Display.INVALID_DISPLAY);
+                mUser, mFlags, mDisplay, overrideConfiguration, Display.INVALID_DISPLAY);
     }
 
     @Override
@@ -1745,7 +1745,7 @@
         }
 
         return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
-                mUser, mRestricted, display, null, Display.INVALID_DISPLAY);
+                mUser, mFlags, display, null, Display.INVALID_DISPLAY);
     }
 
     Display getDisplay() {
@@ -1761,8 +1761,38 @@
     }
 
     @Override
+    public Context createDeviceEncryptedStorageContext() {
+        if (!StorageManager.isFileBasedEncryptionEnabled()) {
+            return null;
+        }
+
+        final int flags = (mFlags & ~Context.CONTEXT_CREDENTIAL_ENCRYPTED_STORAGE)
+                | Context.CONTEXT_DEVICE_ENCRYPTED_STORAGE;
+        return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
+                mUser, flags, mDisplay, null, Display.INVALID_DISPLAY);
+    }
+
+    @Override
+    public Context createCredentialEncryptedStorageContext() {
+        final int flags = (mFlags & ~Context.CONTEXT_DEVICE_ENCRYPTED_STORAGE)
+                | Context.CONTEXT_CREDENTIAL_ENCRYPTED_STORAGE;
+        return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken,
+                mUser, flags, mDisplay, null, Display.INVALID_DISPLAY);
+    }
+
+    @Override
     public boolean isRestricted() {
-        return mRestricted;
+        return (mFlags & Context.CONTEXT_RESTRICTED) != 0;
+    }
+
+    @Override
+    public boolean isDeviceEncryptedStorage() {
+        return (mFlags & Context.CONTEXT_DEVICE_ENCRYPTED_STORAGE) != 0;
+    }
+
+    @Override
+    public boolean isCredentialEncryptedStorage() {
+        return (mFlags & Context.CONTEXT_CREDENTIAL_ENCRYPTED_STORAGE) != 0;
     }
 
     @Override
@@ -1772,7 +1802,13 @@
 
     private File getDataDirFile() {
         if (mPackageInfo != null) {
-            return mPackageInfo.getDataDirFile();
+            if (isCredentialEncryptedStorage()) {
+                return mPackageInfo.getCredentialEncryptedDataDirFile();
+            } else if (isDeviceEncryptedStorage()) {
+                return mPackageInfo.getDeviceEncryptedDataDirFile();
+            } else {
+                return mPackageInfo.getDataDirFile();
+            }
         }
         throw new RuntimeException("Not supported in system context");
     }
@@ -1798,7 +1834,7 @@
     static ContextImpl createSystemContext(ActivityThread mainThread) {
         LoadedApk packageInfo = new LoadedApk(mainThread);
         ContextImpl context = new ContextImpl(null, mainThread,
-                packageInfo, null, null, false, null, null, Display.INVALID_DISPLAY);
+                packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
         context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
                 context.mResourcesManager.getDisplayMetricsLocked());
         return context;
@@ -1807,24 +1843,36 @@
     static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
         if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
         return new ContextImpl(null, mainThread,
-                packageInfo, null, null, false, null, null, Display.INVALID_DISPLAY);
+                packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
     }
 
     static ContextImpl createActivityContext(ActivityThread mainThread,
             LoadedApk packageInfo, int displayId, Configuration overrideConfiguration) {
         if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
-        return new ContextImpl(null, mainThread, packageInfo, null, null, false,
+        return new ContextImpl(null, mainThread, packageInfo, null, null, 0,
                 null, overrideConfiguration, displayId);
     }
 
     private ContextImpl(ContextImpl container, ActivityThread mainThread,
-            LoadedApk packageInfo, IBinder activityToken, UserHandle user, boolean restricted,
+            LoadedApk packageInfo, IBinder activityToken, UserHandle user, int flags,
             Display display, Configuration overrideConfiguration, int createDisplayWithId) {
         mOuterContext = this;
 
+        // If creator didn't specify which storage to use, use the default
+        // location for application.
+        if ((flags & (Context.CONTEXT_CREDENTIAL_ENCRYPTED_STORAGE
+                | Context.CONTEXT_DEVICE_ENCRYPTED_STORAGE)) == 0) {
+            final File dataDir = packageInfo.getDataDirFile();
+            if (Objects.equals(dataDir, packageInfo.getCredentialEncryptedDataDirFile())) {
+                flags |= Context.CONTEXT_CREDENTIAL_ENCRYPTED_STORAGE;
+            } else if (Objects.equals(dataDir, packageInfo.getDeviceEncryptedDataDirFile())) {
+                flags |= Context.CONTEXT_DEVICE_ENCRYPTED_STORAGE;
+            }
+        }
+
         mMainThread = mainThread;
         mActivityToken = activityToken;
-        mRestricted = restricted;
+        mFlags = flags;
 
         if (user == null) {
             user = Process.myUserHandle();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 9a01b7b..eb8d6bc 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -437,7 +437,7 @@
     public void registerUserSwitchObserver(IUserSwitchObserver observer) throws RemoteException;
     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) throws RemoteException;
 
-    public void requestBugReport() throws RemoteException;
+    public void requestBugReport(boolean progress) throws RemoteException;
 
     public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason)
             throws RemoteException;
@@ -541,7 +541,7 @@
 
     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException;
 
-    public void removeStack(int stackId) throws RemoteException;
+    public void moveTasksToFullscreenStack(int fromStackId) throws RemoteException;
 
     public int getAppStartMode(int uid, String packageName) throws RemoteException;
 
@@ -906,7 +906,7 @@
     int REPORT_SIZE_CONFIGURATIONS = IBinder.FIRST_CALL_TRANSACTION + 345;
     int MOVE_TASK_TO_DOCKED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 346;
     int SUPPRESS_RESIZE_CONFIG_CHANGES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 347;
-    int REMOVE_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 348;
+    int MOVE_TASKS_TO_FULLSCREEN_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 348;
     int MOVE_TOP_ACTIVITY_TO_PINNED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 349;
     int GET_APP_START_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 350;
     int UNLOCK_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 351;
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 6c0c3e8..620ab50 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -46,8 +46,10 @@
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.SparseArray;
 import android.util.TypedValue;
 import android.view.Gravity;
+import android.view.NotificationHeaderView;
 import android.view.View;
 import android.widget.ProgressBar;
 import android.widget.RemoteViews;
@@ -63,6 +65,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * A class that represents how a persistent notification is to be presented to
@@ -1692,11 +1695,21 @@
         bigContentView = null;
         headsUpContentView = null;
         mLargeIcon = null;
-        if (extras != null) {
-            extras.remove(Notification.EXTRA_LARGE_ICON);
-            extras.remove(Notification.EXTRA_LARGE_ICON_BIG);
-            extras.remove(Notification.EXTRA_PICTURE);
-            extras.remove(Notification.EXTRA_BIG_TEXT);
+        if (extras != null && !extras.isEmpty()) {
+            final Set<String> keyset = extras.keySet();
+            final int N = keyset.size();
+            final String[] keys = keyset.toArray(new String[N]);
+            for (int i=0; i<N; i++) {
+                final String key = keys[i];
+                final Object obj = extras.get(key);
+                if (obj != null &&
+                    (  obj instanceof Parcelable
+                    || obj instanceof Parcelable[]
+                    || obj instanceof SparseArray
+                    || obj instanceof ArrayList)) {
+                    extras.remove(key);
+                }
+            }
         }
     }
 
@@ -3000,6 +3013,7 @@
          */
         private void resetNotificationHeader(RemoteViews contentView) {
             contentView.setImageViewResource(R.id.icon, 0);
+            contentView.setBoolean(R.id.notification_header, "setExpanded", false);
             contentView.setTextViewText(R.id.app_name_text, null);
             contentView.setViewVisibility(R.id.chronometer, View.GONE);
             contentView.setViewVisibility(R.id.header_sub_text, View.GONE);
@@ -3134,6 +3148,8 @@
         private void bindExpandButton(RemoteViews contentView) {
             contentView.setDrawableParameters(R.id.expand_button, false, -1, resolveColor(),
                     PorterDuff.Mode.SRC_ATOP, -1);
+            contentView.setInt(R.id.notification_header, "setOriginalNotificationColor",
+                    resolveColor());
         }
 
         private void bindHeaderChronometerAndTime(RemoteViews contentView) {
@@ -3197,7 +3213,6 @@
 
         private void resetStandardTemplateWithActions(RemoteViews big) {
             big.setViewVisibility(R.id.actions, View.GONE);
-            big.setViewVisibility(R.id.action_divider, View.GONE);
             big.removeAllViews(R.id.actions);
         }
 
@@ -3209,7 +3224,6 @@
             int N = mActions.size();
             if (N > 0) {
                 big.setViewVisibility(R.id.actions, View.VISIBLE);
-                big.setViewVisibility(R.id.action_divider, View.VISIBLE);
                 if (N>MAX_ACTION_BUTTONS) N=MAX_ACTION_BUTTONS;
                 for (int i=0; i<N; i++) {
                     final RemoteViews button = generateActionButton(mActions.get(i));
@@ -3276,11 +3290,7 @@
         }
 
         private void adaptNotificationHeaderForBigContentView(RemoteViews result) {
-            // We have to set the collapse button instead
-            result.setImageViewResource(R.id.expand_button, R.drawable.ic_arrow_up_14dp);
-            // Apply the color again
-            result.setDrawableParameters(R.id.expand_button, false, -1, resolveColor(),
-                    PorterDuff.Mode.SRC_ATOP, -1);
+            result.setBoolean(R.id.notification_header, "setExpanded", true);
         }
 
         /**
@@ -3320,7 +3330,6 @@
             if (mN.color != COLOR_DEFAULT) {
                 button.setTextColor(R.id.action0, mN.color);
             }
-            processLegacyAction(action, button);
             return button;
         }
 
@@ -3332,14 +3341,6 @@
             return getColorUtil() != null;
         }
 
-        private void processLegacyAction(Action action, RemoteViews button) {
-            if (!isLegacy() || getColorUtil().isGrayscaleIcon(mContext, action.getIcon())) {
-                button.setTextViewCompoundDrawablesRelativeColorFilter(R.id.action0, 0,
-                        mContext.getColor(R.color.notification_action_color_filter),
-                        PorterDuff.Mode.MULTIPLY);
-            }
-        }
-
         private CharSequence processLegacyText(CharSequence charSequence) {
             if (isLegacy()) {
                 return getColorUtil().invertCharSequenceColors(charSequence);
@@ -3352,10 +3353,14 @@
          * Apply any necessariy colors to the small icon
          */
         private void processSmallIconColor(Icon smallIcon, RemoteViews contentView) {
-            if (!isLegacy() || getColorUtil().isGrayscaleIcon(mContext, smallIcon)) {
+            boolean colorable = !isLegacy() || getColorUtil().isGrayscaleIcon(mContext, smallIcon);
+            if (colorable) {
                 contentView.setDrawableParameters(R.id.icon, false, -1, resolveColor(),
                         PorterDuff.Mode.SRC_ATOP, -1);
+
             }
+            contentView.setInt(R.id.notification_header, "setOriginalIconColor",
+                    colorable ? resolveColor() : NotificationHeaderView.NO_COLOR);
         }
 
         /**
diff --git a/core/java/android/app/SynchronousUserSwitchObserver.java b/core/java/android/app/SynchronousUserSwitchObserver.java
new file mode 100644
index 0000000..6d929f9
--- /dev/null
+++ b/core/java/android/app/SynchronousUserSwitchObserver.java
@@ -0,0 +1,48 @@
+/*
+ * 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.app;
+
+import android.os.Bundle;
+import android.os.IRemoteCallback;
+import android.os.RemoteException;
+
+/**
+ * Base class for synchronous implementations of {@link IUserSwitchObserver}
+ *
+ * @hide
+ */
+public abstract class SynchronousUserSwitchObserver extends IUserSwitchObserver.Stub {
+    /**
+     * Calls {@link #onUserSwitching(int)} and notifies {@code reply} by calling
+     * {@link IRemoteCallback#sendResult(Bundle)}.
+     */
+    @Override
+    public final void onUserSwitching(int newUserId, IRemoteCallback reply) throws RemoteException {
+        try {
+            onUserSwitching(newUserId);
+        } finally {
+            if (reply != null) {
+                reply.sendResult(null);
+            }
+        }
+    }
+
+    /**
+     * Synchronous version of {@link IUserSwitchObserver#onUserSwitching(int, IRemoteCallback)}
+     */
+    public abstract void onUserSwitching(int newUserId) throws RemoteException;
+}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 471750e..93f137f 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -89,7 +89,6 @@
     private final Context mContext;
     private final IDevicePolicyManager mService;
 
-    // TODO Use it everywhere.
     private static final String REMOTE_EXCEPTION_MESSAGE =
             "Failed to talk with device policy manager service";
 
@@ -841,7 +840,7 @@
             try {
                 return mService.isAdminActive(admin, userId);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return false;
@@ -856,7 +855,7 @@
             try {
                 return mService.isRemovingAdmin(admin, userId);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return false;
@@ -881,7 +880,7 @@
             try {
                 return mService.getActiveAdmins(userId);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return null;
@@ -897,7 +896,7 @@
             try {
                 return mService.packageHasActiveAdmins(packageName, myUserId());
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return false;
@@ -914,7 +913,7 @@
             try {
                 mService.removeActiveAdmin(admin, myUserId());
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -933,7 +932,7 @@
             try {
                 return mService.hasGrantedPolicy(admin, usesPolicy, myUserId());
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return false;
@@ -1034,7 +1033,7 @@
             try {
                 mService.setPasswordQuality(admin, quality);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -1055,7 +1054,7 @@
             try {
                 return mService.getPasswordQuality(admin, userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return PASSWORD_QUALITY_UNSPECIFIED;
@@ -1087,7 +1086,7 @@
             try {
                 mService.setPasswordMinimumLength(admin, length);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -1108,7 +1107,7 @@
             try {
                 return mService.getPasswordMinimumLength(admin, userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return 0;
@@ -1141,7 +1140,7 @@
             try {
                 mService.setPasswordMinimumUpperCase(admin, length);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -1169,7 +1168,7 @@
             try {
                 return mService.getPasswordMinimumUpperCase(admin, userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return 0;
@@ -1202,7 +1201,7 @@
             try {
                 mService.setPasswordMinimumLowerCase(admin, length);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -1230,7 +1229,7 @@
             try {
                 return mService.getPasswordMinimumLowerCase(admin, userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return 0;
@@ -1262,7 +1261,7 @@
             try {
                 mService.setPasswordMinimumLetters(admin, length);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -1288,7 +1287,7 @@
             try {
                 return mService.getPasswordMinimumLetters(admin, userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return 0;
@@ -1320,7 +1319,7 @@
             try {
                 mService.setPasswordMinimumNumeric(admin, length);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -1347,7 +1346,7 @@
             try {
                 return mService.getPasswordMinimumNumeric(admin, userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return 0;
@@ -1379,7 +1378,7 @@
             try {
                 mService.setPasswordMinimumSymbols(admin, length);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -1405,7 +1404,7 @@
             try {
                 return mService.getPasswordMinimumSymbols(admin, userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return 0;
@@ -1437,7 +1436,7 @@
             try {
                 mService.setPasswordMinimumNonLetter(admin, length);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -1464,7 +1463,7 @@
             try {
                 return mService.getPasswordMinimumNonLetter(admin, userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return 0;
@@ -1497,7 +1496,7 @@
             try {
                 mService.setPasswordHistoryLength(admin, length);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -1529,7 +1528,7 @@
             try {
                 mService.setPasswordExpirationTimeout(admin, timeout);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -1548,7 +1547,7 @@
             try {
                 return mService.getPasswordExpirationTimeout(admin, myUserId());
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return 0;
@@ -1569,7 +1568,7 @@
             try {
                 return mService.getPasswordExpiration(admin, myUserId());
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return 0;
@@ -1592,7 +1591,7 @@
             try {
                 return mService.getPasswordHistoryLength(admin, userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return 0;
@@ -1625,7 +1624,7 @@
             try {
                 return mService.isActivePasswordSufficient(myUserId());
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return false;
@@ -1644,7 +1643,7 @@
             try {
                 return mService.getCurrentFailedPasswordAttempts(myUserId());
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return -1;
@@ -1661,7 +1660,7 @@
             try {
                 return mService.getDoNotAskCredentialsOnBoot();
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed to call getDoNotAskCredentialsOnBoot()", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return false;
@@ -1691,7 +1690,7 @@
             try {
                 mService.setMaximumFailedPasswordsForWipe(admin, num);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -1713,7 +1712,7 @@
             try {
                 return mService.getMaximumFailedPasswordsForWipe(admin, userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return 0;
@@ -1731,7 +1730,7 @@
             try {
                 return mService.getProfileWithMinimumFailedPasswordsForWipe(userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return UserHandle.USER_NULL;
@@ -1796,7 +1795,7 @@
             try {
                 return mService.resetPassword(password, flags);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return false;
@@ -1820,7 +1819,7 @@
             try {
                 mService.setMaximumTimeToLock(admin, timeMs);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -1843,7 +1842,7 @@
             try {
                 return mService.getMaximumTimeToLock(admin, userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return 0;
@@ -1862,7 +1861,7 @@
             try {
                 mService.lockNow();
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -1899,7 +1898,7 @@
             try {
                 mService.wipeData(flags);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -1969,7 +1968,7 @@
                 }
                 return mService.setGlobalProxy(admin, hostSpec, exclSpec);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return null;
@@ -1997,7 +1996,7 @@
             try {
                 mService.setRecommendedGlobalProxy(admin, proxyInfo);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -2013,7 +2012,7 @@
             try {
                 return mService.getGlobalProxyAdmin(myUserId());
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return null;
@@ -2143,7 +2142,7 @@
             try {
                 return mService.setStorageEncryption(admin, encrypt);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return ENCRYPTION_STATUS_UNSUPPORTED;
@@ -2163,7 +2162,7 @@
             try {
                 return mService.getStorageEncryption(admin, myUserId());
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return false;
@@ -2198,7 +2197,7 @@
             try {
                 return mService.getStorageEncryptionStatus(userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return ENCRYPTION_STATUS_UNSUPPORTED;
@@ -2219,7 +2218,7 @@
             try {
                 return mService.installCaCert(admin, certBuffer);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return false;
@@ -2240,7 +2239,7 @@
             } catch (CertificateException e) {
                 Log.w(TAG, "Unable to parse certificate", e);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -2268,7 +2267,7 @@
                     }
                 }
             } catch (RemoteException re) {
-                Log.w(TAG, "Failed talking with device policy service", re);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
         return certs;
@@ -2287,7 +2286,7 @@
                 mService.uninstallCaCerts(admin, new TrustedCertificateStore().userAliases()
                         .toArray(new String[0]));
             } catch (RemoteException re) {
-                Log.w(TAG, "Failed talking with device policy service", re);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
     }
@@ -2305,7 +2304,7 @@
                 mService.enforceCanManageCaCerts(admin);
                 return getCaCertAlias(certBuffer) != null;
             } catch (RemoteException re) {
-                Log.w(TAG, "Failed talking with device policy service", re);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             } catch (CertificateException ce) {
                 Log.w(TAG, "Could not parse certificate", ce);
             }
@@ -2325,15 +2324,15 @@
      * with that alias already exists, it will be overwritten.
      * @return {@code true} if the keys were installed, {@code false} otherwise.
      */
-    public boolean installKeyPair(@Nullable ComponentName admin, PrivateKey privKey, Certificate cert,
-            String alias) {
+    public boolean installKeyPair(@Nullable ComponentName admin, @NonNull PrivateKey privKey,
+            @NonNull Certificate cert, @NonNull String alias) {
         try {
             final byte[] pemCert = Credentials.convertToPem(cert);
             final byte[] pkcs8Key = KeyFactory.getInstance(privKey.getAlgorithm())
                     .getKeySpec(privKey, PKCS8EncodedKeySpec.class).getEncoded();
             return mService.installKeyPair(admin, pkcs8Key, pemCert, alias);
         } catch (RemoteException e) {
-            Log.w(TAG, "Failed talking with device policy service", e);
+            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
         } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
             Log.w(TAG, "Failed to obtain private key material", e);
         } catch (CertificateException | IOException e) {
@@ -2343,6 +2342,24 @@
     }
 
     /**
+     * Called by a device or profile owner to remove all user credentials installed under a given
+     * alias.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
+     *            {@code null} if calling from a delegated certificate installer.
+     * @param alias The private key alias under which the certificate is installed.
+     * @return {@code true} if the keys were both removed, {@code false} otherwise.
+     */
+    public boolean removeKeyPair(@Nullable ComponentName admin, @NonNull String alias) {
+        try {
+            return mService.removeKeyPair(admin, alias);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed talking with device policy service", e);
+        }
+        return false;
+    }
+
+    /**
      * @return the alias of a given CA certificate in the certificate store, or {@code null} if it
      * doesn't exist.
      */
@@ -2373,7 +2390,7 @@
             try {
                 mService.setCertInstallerPackage(admin, installerPackage);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -2391,7 +2408,7 @@
             try {
                 return mService.getCertInstallerPackage(admin);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return null;
@@ -2416,7 +2433,7 @@
             try {
                 mService.setCameraDisabled(admin, disabled);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -2437,7 +2454,7 @@
             try {
                 return mService.getCameraDisabled(admin, userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return false;
@@ -2474,7 +2491,7 @@
             try {
                 mService.setScreenCaptureDisabled(admin, disabled);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -2495,7 +2512,7 @@
             try {
                 return mService.getScreenCaptureDisabled(admin, userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return false;
@@ -2518,7 +2535,7 @@
             try {
                 mService.setAutoTimeRequired(admin, required);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -2531,7 +2548,7 @@
             try {
                 return mService.getAutoTimeRequired();
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return false;
@@ -2572,7 +2589,7 @@
             try {
                 mService.setKeyguardDisabledFeatures(admin, which);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -2595,7 +2612,7 @@
             try {
                 return mService.getKeyguardDisabledFeatures(admin, userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return KEYGUARD_DISABLE_FEATURES_NONE;
@@ -2610,7 +2627,7 @@
             try {
                 mService.setActiveAdmin(policyReceiver, refreshing, userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -2641,10 +2658,7 @@
 
         try {
             return new DeviceAdminInfo(mContext, ri);
-        } catch (XmlPullParserException e) {
-            Log.w(TAG, "Unable to parse device policy " + cn, e);
-            return null;
-        } catch (IOException e) {
+        } catch (XmlPullParserException | IOException e) {
             Log.w(TAG, "Unable to parse device policy " + cn, e);
             return null;
         }
@@ -2658,7 +2672,7 @@
             try {
                 mService.getRemoveWarning(admin, result, myUserId());
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -2673,7 +2687,7 @@
                 mService.setActivePasswordState(quality, length, letters, uppercase, lowercase,
                         numbers, symbols, nonletter, userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -2686,7 +2700,7 @@
             try {
                 mService.reportFailedPasswordAttempt(userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -2699,7 +2713,7 @@
             try {
                 mService.reportSuccessfulPasswordAttempt(userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -2752,7 +2766,7 @@
             try {
                 return mService.setDeviceOwner(who, ownerName, userId);
             } catch (RemoteException re) {
-                Log.w(TAG, "Failed to set device owner");
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
         return false;
@@ -2834,7 +2848,7 @@
             try {
                 return mService.getDeviceOwnerComponent(callingUserOnly);
             } catch (RemoteException re) {
-                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
         return null;
@@ -2853,7 +2867,7 @@
             try {
                 return mService.getDeviceOwnerUserId();
             } catch (RemoteException re) {
-                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
         return UserHandle.USER_NULL;
@@ -2873,7 +2887,7 @@
             try {
                 mService.clearDeviceOwner(packageName);
             } catch (RemoteException re) {
-                Log.w(TAG, "Failed to clear device owner");
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
     }
@@ -2915,7 +2929,7 @@
             try {
                 return mService.getDeviceOwnerName();
             } catch (RemoteException re) {
-                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
         return null;
@@ -2968,7 +2982,6 @@
                 mService.setActiveAdmin(admin, false, myUserId);
                 return mService.setProfileOwner(admin, ownerName, myUserId);
             } catch (RemoteException re) {
-                Log.w(TAG, "Failed to set profile owner " + re);
                 throw new IllegalArgumentException("Couldn't set profile owner.", re);
             }
         }
@@ -2990,7 +3003,7 @@
             try {
                 mService.clearProfileOwner(admin);
             } catch (RemoteException re) {
-                Log.w(TAG, "Failed to clear profile owner " + admin + re);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
     }
@@ -3004,7 +3017,7 @@
             try {
                 return mService.hasUserSetupCompleted();
             } catch (RemoteException re) {
-                Log.w(TAG, "Failed to check whether user setup has completed");
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
         return true;
@@ -3035,7 +3048,7 @@
                 }
                 return mService.setProfileOwner(admin, ownerName, userHandle);
             } catch (RemoteException re) {
-                Log.w(TAG, "Failed to set profile owner", re);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
                 throw new IllegalArgumentException("Couldn't set profile owner.", re);
             }
         }
@@ -3058,7 +3071,7 @@
             try {
                 return mService.setDeviceOwnerLockScreenInfo(admin, info);
             } catch (RemoteException re) {
-                Log.w(TAG, "Failed talking with device policy service", re);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
         return false;
@@ -3072,7 +3085,7 @@
             try {
                 return mService.getDeviceOwnerLockScreenInfo();
             } catch (RemoteException re) {
-                Log.w(TAG, "Failed talking with device policy service", re);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
         return null;
@@ -3091,7 +3104,7 @@
             try {
                 mService.setProfileEnabled(admin);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -3112,7 +3125,7 @@
             try {
                 mService.setProfileName(admin, profileName);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -3133,7 +3146,7 @@
                 return profileOwner != null
                         && profileOwner.getPackageName().equals(packageName);
             } catch (RemoteException re) {
-                Log.w(TAG, "Failed to check profile owner");
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
         return false;
@@ -3159,7 +3172,7 @@
             try {
                 return mService.getProfileOwner(userId);
             } catch (RemoteException re) {
-                Log.w(TAG, "Failed to get profile owner");
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
                 throw new IllegalArgumentException(
                         "Requested profile owner for invalid userId", re);
             }
@@ -3178,7 +3191,7 @@
             try {
                 return mService.getProfileOwnerName(Process.myUserHandle().getIdentifier());
             } catch (RemoteException re) {
-                Log.w(TAG, "Failed to get profile owner");
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
                 throw new IllegalArgumentException(
                         "Requested profile owner for invalid userId", re);
             }
@@ -3199,7 +3212,7 @@
             try {
                 return mService.getProfileOwnerName(userId);
             } catch (RemoteException re) {
-                Log.w(TAG, "Failed to get profile owner");
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
                 throw new IllegalArgumentException(
                         "Requested profile owner for invalid userId", re);
             }
@@ -3230,7 +3243,7 @@
             try {
                 mService.addPersistentPreferredActivity(admin, filter, activity);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -3251,7 +3264,7 @@
             try {
                 mService.clearPackagePersistentPreferredActivities(admin, packageName);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -3291,7 +3304,7 @@
             try {
                 mService.setApplicationRestrictions(admin, packageName, settings);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -3321,7 +3334,7 @@
             try {
                 mService.setTrustAgentConfiguration(admin, target, configuration);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -3352,7 +3365,7 @@
             try {
                 return mService.getTrustAgentConfiguration(admin, agent, userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return new ArrayList<PersistableBundle>(); // empty list
@@ -3373,7 +3386,7 @@
             try {
                 mService.setCrossProfileCallerIdDisabled(admin, disabled);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -3392,7 +3405,7 @@
             try {
                 return mService.getCrossProfileCallerIdDisabled(admin);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return false;
@@ -3409,7 +3422,7 @@
             try {
                 return mService.getCrossProfileCallerIdDisabledForUser(userHandle.getIdentifier());
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return false;
@@ -3426,7 +3439,7 @@
                 mService.startManagedQuickContact(
                         actualLookupKey, actualContactId, directoryId, originalIntent);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -3460,7 +3473,7 @@
             try {
                 mService.setBluetoothContactSharingDisabled(admin, disabled);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -3482,7 +3495,7 @@
             try {
                 return mService.getBluetoothContactSharingDisabled(admin);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return true;
@@ -3502,7 +3515,7 @@
                 return mService.getBluetoothContactSharingDisabledForUser(userHandle
                         .getIdentifier());
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return true;
@@ -3524,7 +3537,7 @@
             try {
                 mService.addCrossProfileIntentFilter(admin, filter, flags);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -3540,7 +3553,7 @@
             try {
                 mService.clearCrossProfileIntentFilters(admin);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -3572,7 +3585,7 @@
             try {
                 return mService.setPermittedAccessibilityServices(admin, packageNames);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return false;
@@ -3592,7 +3605,7 @@
             try {
                 return mService.getPermittedAccessibilityServices(admin);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return null;
@@ -3616,7 +3629,7 @@
             try {
                 return mService.getPermittedAccessibilityServicesForUser(userId);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return null;
@@ -3650,7 +3663,7 @@
             try {
                 return mService.setPermittedInputMethods(admin, packageNames);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return false;
@@ -3671,7 +3684,7 @@
             try {
                 return mService.getPermittedInputMethods(admin);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return null;
@@ -3694,7 +3707,7 @@
             try {
                 return mService.getPermittedInputMethodsForCurrentUser();
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return null;
@@ -3714,7 +3727,7 @@
             try {
                 return mService.getKeepUninstalledPackages(admin);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return null;
@@ -3737,7 +3750,7 @@
             try {
                 mService.setKeepUninstalledPackages(admin, packageNames);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -3761,7 +3774,7 @@
         try {
             return mService.createUser(admin, name);
         } catch (RemoteException re) {
-            Log.w(TAG, "Could not create a user", re);
+            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
         }
         return null;
     }
@@ -3800,7 +3813,7 @@
             return mService.createAndInitializeUser(admin, name, ownerName, profileOwnerComponent,
                     adminExtras);
         } catch (RemoteException re) {
-            Log.w(TAG, "Could not create a user", re);
+            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
         }
         return null;
     }
@@ -3817,7 +3830,7 @@
         try {
             return mService.removeUser(admin, userHandle);
         } catch (RemoteException re) {
-            Log.w(TAG, "Could not remove user ", re);
+            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             return false;
         }
     }
@@ -3835,7 +3848,7 @@
         try {
             return mService.switchUser(admin, userHandle);
         } catch (RemoteException re) {
-            Log.w(TAG, "Could not switch user ", re);
+            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             return false;
         }
     }
@@ -3858,7 +3871,7 @@
             try {
                 return mService.getApplicationRestrictions(admin, packageName);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return null;
@@ -3880,7 +3893,7 @@
             try {
                 mService.setUserRestriction(admin, key, true);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -3901,7 +3914,7 @@
             try {
                 mService.setUserRestriction(admin, key, false);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -3928,7 +3941,7 @@
             try {
                 ret = mService.getUserRestrictions(admin, userHandle);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return ret == null ? new Bundle() : ret;
@@ -3950,7 +3963,7 @@
             try {
                 return mService.setApplicationHidden(admin, packageName, hidden);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return false;
@@ -3968,7 +3981,7 @@
             try {
                 return mService.isApplicationHidden(admin, packageName);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return false;
@@ -3986,7 +3999,7 @@
             try {
                 mService.enableSystemApp(admin, packageName);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed to install package: " + packageName);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -4005,7 +4018,7 @@
             try {
                 return mService.enableSystemAppWithIntent(admin, intent);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed to install packages matching filter: " + intent);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return 0;
@@ -4032,7 +4045,7 @@
             try {
                 mService.setAccountManagementDisabled(admin, accountType, disabled);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -4060,7 +4073,7 @@
             try {
                 return mService.getAccountTypesWithManagementDisabledAsUser(userId);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
 
@@ -4091,7 +4104,7 @@
             try {
                 mService.setLockTaskPackages(admin, packages);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -4107,7 +4120,7 @@
             try {
                 return mService.getLockTaskPackages(admin);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return null;
@@ -4123,7 +4136,7 @@
             try {
                 return mService.isLockTaskPermitted(pkg);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
         return false;
@@ -4170,7 +4183,7 @@
             try {
                 mService.setGlobalSetting(admin, setting, value);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -4198,7 +4211,7 @@
             try {
                 mService.setSecureSetting(admin, setting, value);
             } catch (RemoteException e) {
-                Log.w(TAG, "Failed talking with device policy service", e);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
         }
     }
@@ -4219,7 +4232,7 @@
             try {
                 mService.setRestrictionsProvider(admin, provider);
             } catch (RemoteException re) {
-                Log.w(TAG, "Failed to set permission provider on device policy service");
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
     }
@@ -4235,7 +4248,7 @@
             try {
                 mService.setMasterVolumeMuted(admin, on);
             } catch (RemoteException re) {
-                Log.w(TAG, "Failed to setMasterMute on device policy service");
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
     }
@@ -4251,7 +4264,7 @@
             try {
                 return mService.isMasterVolumeMuted(admin);
             } catch (RemoteException re) {
-                Log.w(TAG, "Failed to get isMasterMute on device policy service");
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
         return false;
@@ -4271,7 +4284,7 @@
             try {
                 mService.setUninstallBlocked(admin, packageName, uninstallBlocked);
             } catch (RemoteException re) {
-                Log.w(TAG, "Failed to call block uninstall on device policy service");
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
     }
@@ -4295,7 +4308,7 @@
             try {
                 return mService.isUninstallBlocked(admin, packageName);
             } catch (RemoteException re) {
-                Log.w(TAG, "Failed to call block uninstall on device policy service");
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
         return false;
@@ -4323,7 +4336,7 @@
             try {
                 return mService.addCrossProfileWidgetProvider(admin, packageName);
             } catch (RemoteException re) {
-                Log.w(TAG, "Error calling addCrossProfileWidgetProvider", re);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
         return false;
@@ -4350,7 +4363,7 @@
             try {
                 return mService.removeCrossProfileWidgetProvider(admin, packageName);
             } catch (RemoteException re) {
-                Log.w(TAG, "Error calling removeCrossProfileWidgetProvider", re);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
         return false;
@@ -4374,7 +4387,7 @@
                     return providers;
                 }
             } catch (RemoteException re) {
-                Log.w(TAG, "Error calling getCrossProfileWidgetProviders", re);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
         return Collections.emptyList();
@@ -4390,7 +4403,7 @@
         try {
             mService.setUserIcon(admin, icon);
         } catch (RemoteException re) {
-            Log.w(TAG, "Could not set the user icon ", re);
+            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
         }
     }
 
@@ -4410,7 +4423,7 @@
             try {
                 mService.setSystemUpdatePolicy(admin, policy);
             } catch (RemoteException re) {
-                Log.w(TAG, "Error calling setSystemUpdatePolicy", re);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
     }
@@ -4425,7 +4438,7 @@
             try {
                 return mService.getSystemUpdatePolicy();
             } catch (RemoteException re) {
-                Log.w(TAG, "Error calling getSystemUpdatePolicy", re);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
         return null;
@@ -4449,7 +4462,7 @@
         try {
             return mService.setKeyguardDisabled(admin, disabled);
         } catch (RemoteException re) {
-            Log.w(TAG, "Failed talking with device policy service", re);
+            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             return false;
         }
     }
@@ -4469,7 +4482,7 @@
         try {
             return mService.setStatusBarDisabled(admin, disabled);
         } catch (RemoteException re) {
-            Log.w(TAG, "Failed talking with device policy service", re);
+            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             return false;
         }
     }
@@ -4489,7 +4502,7 @@
             try {
                 mService.notifyPendingSystemUpdate(updateReceivedTime);
             } catch (RemoteException re) {
-                Log.w(TAG, "Could not notify device owner about pending system update", re);
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             }
         }
     }
@@ -4515,7 +4528,7 @@
         try {
             mService.setPermissionPolicy(admin, policy);
         } catch (RemoteException re) {
-            Log.w(TAG, "Failed talking with device policy service", re);
+            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
         }
     }
 
@@ -4566,7 +4579,7 @@
         try {
             return mService.setPermissionGrantState(admin, packageName, permission, grantState);
         } catch (RemoteException re) {
-            Log.w(TAG, "Failed talking with device policy service", re);
+            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             return false;
         }
     }
@@ -4593,7 +4606,7 @@
         try {
             return mService.getPermissionGrantState(admin, packageName, permission);
         } catch (RemoteException re) {
-            Log.w(TAG, "Failed talking with device policy service", re);
+            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             return PERMISSION_GRANT_STATE_DEFAULT;
         }
     }
@@ -4612,7 +4625,7 @@
         try {
             return mService.isProvisioningAllowed(action);
         } catch (RemoteException re) {
-            Log.w(TAG, "Failed talking with device policy service", re);
+            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             return false;
         }
     }
@@ -4629,7 +4642,7 @@
         try {
             return mService.isManagedProfile(admin);
         } catch (RemoteException re) {
-            Log.w(TAG, "Failed talking with device policy service", re);
+            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             return false;
         }
     }
@@ -4645,7 +4658,7 @@
         try {
             return mService.isSystemOnlyUser(admin);
         } catch (RemoteException re) {
-            Log.w(TAG, "Failed talking with device policy service", re);
+            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             return false;
         }
     }
@@ -4662,7 +4675,7 @@
         try {
             return mService.getWifiMacAddress();
         } catch (RemoteException re) {
-            Log.w(TAG, "Failed talking with device policy service", re);
+            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
             return null;
         }
     }
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 6b4567c..1708ee3 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -135,6 +135,7 @@
     void enforceCanManageCaCerts(in ComponentName admin);
 
     boolean installKeyPair(in ComponentName who, in byte[] privKeyBuffer, in byte[] certBuffer, String alias);
+    boolean removeKeyPair(in ComponentName who, String alias);
     void choosePrivateKeyAlias(int uid, in Uri uri, in String alias, IBinder aliasCallback);
 
     void setCertInstallerPackage(in ComponentName who, String installerPackage);
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClientCall.java b/core/java/android/bluetooth/BluetoothHeadsetClientCall.java
index 7b5a045..1fb7825 100644
--- a/core/java/android/bluetooth/BluetoothHeadsetClientCall.java
+++ b/core/java/android/bluetooth/BluetoothHeadsetClientCall.java
@@ -172,8 +172,12 @@
     }
 
     public String toString() {
+        return toString(false);
+    }
+
+    public String toString(boolean loggable) {
         StringBuilder builder = new StringBuilder("BluetoothHeadsetClientCall{mDevice: ");
-        builder.append(mDevice);
+        builder.append(loggable ? mDevice.hashCode() : mDevice);
         builder.append(", mId: ");
         builder.append(mId);
         builder.append(", mState: ");
@@ -189,7 +193,7 @@
             default: builder.append(mState); break;
         }
         builder.append(", mNumber: ");
-        builder.append(mNumber);
+        builder.append(loggable ? mNumber.hashCode() : mNumber);
         builder.append(", mMultiParty: ");
         builder.append(mMultiParty);
         builder.append(", mOutgoing: ");
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 6cc5497..38a4475 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -53,8 +53,8 @@
 import android.os.UserManager;
 import android.provider.MediaStore;
 import android.util.AttributeSet;
-import android.view.DisplayAdjustments;
 import android.view.Display;
+import android.view.DisplayAdjustments;
 import android.view.ViewDebug;
 import android.view.WindowManager;
 
@@ -606,13 +606,13 @@
     public abstract String getPackageCodePath();
 
     /**
-     * {@hide}
-     * Return the full path to the shared prefs file for the given prefs group name.
-     *
-     * <p>Note: this is not generally useful for applications, since they should
-     * not be directly accessing the file system.
+     * @hide
+     * @deprecated use {@link #getSharedPreferencesPath(String)}
      */
-    public abstract File getSharedPrefsFile(String name);
+    @Deprecated
+    public File getSharedPrefsFile(String name) {
+        return getSharedPreferencesPath(name);
+    }
 
     /**
      * Retrieve and hold the contents of the preferences file 'name', returning
@@ -654,6 +654,7 @@
      * @return The single {@link SharedPreferences} instance that can be used
      *         to retrieve and modify the preference values.
      *
+     * @see #getSharedPreferencesPath(String)
      * @see #MODE_PRIVATE
      * @see #MODE_WORLD_READABLE
      * @see #MODE_WORLD_WRITEABLE
@@ -739,6 +740,20 @@
     public abstract File getFileStreamPath(String name);
 
     /**
+     * Returns the absolute path on the filesystem where a file created with
+     * {@link #getSharedPreferences(String, int)} is stored.
+     * <p>
+     * The returned path may change over time if the calling app is moved to an
+     * adopted storage device, so only relative paths should be persisted.
+     *
+     * @param name The name of the shared preferences for which you would like
+     *            to get a path.
+     * @return An absolute path to the given file.
+     * @see #getSharedPreferences(String, int)
+     */
+    public abstract File getSharedPreferencesPath(String name);
+
+    /**
      * Returns the absolute path to the directory on the filesystem where files
      * created with {@link #openFileOutput} are stored.
      * <p>
@@ -756,27 +771,6 @@
     public abstract File getFilesDir();
 
     /**
-     * Return the filesystem directory for storing device-encrypted private app
-     * data. Files stored in this location are typically encrypted with a key
-     * tied to the physical device, and they can be accessed whenever the device
-     * has booted successfully, both <em>before and after</em> the user has
-     * entered their credentials (such as a lock pattern or PIN).
-     */
-    public abstract File getDeviceEncryptedFilesDir();
-
-    /**
-     * Return the filesystem directory for storing credential-encrypted private
-     * app data. Files stored in this location are typically encrypted with a
-     * key tied to user credentials, and they can be accessed
-     * <em>only after</em> the user has entered their credentials (such as a
-     * lock pattern or PIN).
-     *
-     * @hide
-     */
-    @SystemApi
-    public abstract File getCredentialEncryptedFilesDir();
-
-    /**
      * Returns the absolute path to the directory on the filesystem similar to
      * {@link #getFilesDir()}. The difference is that files placed under this
      * directory will be excluded from automatic backup to remote storage. See
@@ -2122,6 +2116,14 @@
             UserHandle user);
 
     /**
+     * @hide
+     * This is just here for sending CONNECTIVITY_ACTION.
+     */
+    @Deprecated
+    public abstract void sendStickyBroadcastAsUser(@RequiresPermission Intent intent,
+            UserHandle user, Bundle options);
+
+    /**
      * <p>Version of
      * {@link #sendStickyOrderedBroadcast(Intent, BroadcastReceiver, Handler, int, String, Bundle)}
      * that allows you to specify the
@@ -3871,6 +3873,22 @@
     public static final int CONTEXT_RESTRICTED = 0x00000004;
 
     /**
+     * Flag for use with {@link #createPackageContext}: point all file APIs at
+     * device-encrypted storage.
+     *
+     * @hide
+     */
+    public static final int CONTEXT_DEVICE_ENCRYPTED_STORAGE = 0x00000008;
+
+    /**
+     * Flag for use with {@link #createPackageContext}: point all file APIs at
+     * credential-encrypted storage.
+     *
+     * @hide
+     */
+    public static final int CONTEXT_CREDENTIAL_ENCRYPTED_STORAGE = 0x00000010;
+
+    /**
      * @hide Used to indicate we should tell the activity manager about the process
      * loading this code.
      */
@@ -3970,6 +3988,48 @@
     public abstract Context createDisplayContext(@NonNull Display display);
 
     /**
+     * Return a new Context object for the current Context but whose storage
+     * APIs are backed by device-encrypted storage.
+     * <p>
+     * Data stored in device-encrypted storage is typically encrypted with a key
+     * tied to the physical device, and it can be accessed when the device has
+     * booted successfully, both <em>before and after</em> the user has
+     * authenticated with their credentials (such as a lock pattern or PIN).
+     * Because device-encrypted data is available before user authentication,
+     * you should carefully consider what data you store using this Context.
+     * <p>
+     * Each call to this method returns a new instance of a Context object;
+     * Context objects are not shared, however common state (ClassLoader, other
+     * Resources for the same configuration) may be so the Context itself can be
+     * fairly lightweight.
+     *
+     * @return new Context or {@code null} if device-encrypted storage is not
+     *         supported or available on this device.
+     * @see #isDeviceEncryptedStorage()
+     */
+    public abstract Context createDeviceEncryptedStorageContext();
+
+    /**
+     * Return a new Context object for the current Context but whose storage
+     * APIs are backed by credential-encrypted storage.
+     * <p>
+     * Data stored in credential-encrypted storage is typically encrypted with a
+     * key tied to user credentials, and they can be accessed
+     * <em>only after</em> the user has entered their credentials (such as a
+     * lock pattern or PIN).
+     * <p>
+     * Each call to this method returns a new instance of a Context object;
+     * Context objects are not shared, however common state (ClassLoader, other
+     * Resources for the same configuration) may be so the Context itself can be
+     * fairly lightweight.
+     *
+     * @see #isCredentialEncryptedStorage()
+     * @hide
+     */
+    @SystemApi
+    public abstract Context createCredentialEncryptedStorageContext();
+
+    /**
      * Gets the display adjustments holder for this context.  This information
      * is provided on a per-application or activity basis and is used to simulate lower density
      * display metrics for legacy applications and restricted screen sizes.
@@ -3990,4 +4050,22 @@
     public boolean isRestricted() {
         return false;
     }
+
+    /**
+     * Indicates if the storage APIs of this Context are backed by
+     * device-encrypted storage.
+     *
+     * @see #createDeviceEncryptedStorageContext()
+     */
+    public abstract boolean isDeviceEncryptedStorage();
+
+    /**
+     * Indicates if the storage APIs of this Context are backed by
+     * credential-encrypted storage.
+     *
+     * @see #createCredentialEncryptedStorageContext()
+     * @hide
+     */
+    @SystemApi
+    public abstract boolean isCredentialEncryptedStorage();
 }
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index a345aae..1a3d262 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -160,12 +160,6 @@
         return mBase.getPackageCodePath();
     }
 
-    /** @hide */
-    @Override
-    public File getSharedPrefsFile(String name) {
-        return mBase.getSharedPrefsFile(name);
-    }
-
     @Override
     public SharedPreferences getSharedPreferences(String name, int mode) {
         return mBase.getSharedPreferences(name, mode);
@@ -199,6 +193,11 @@
     }
 
     @Override
+    public File getSharedPreferencesPath(String name) {
+        return mBase.getSharedPreferencesPath(name);
+    }
+
+    @Override
     public String[] fileList() {
         return mBase.fileList();
     }
@@ -209,18 +208,6 @@
     }
 
     @Override
-    public File getDeviceEncryptedFilesDir() {
-        return mBase.getDeviceEncryptedFilesDir();
-    }
-
-    /** {@hide} */
-    @SystemApi
-    @Override
-    public File getCredentialEncryptedFilesDir() {
-        return mBase.getCredentialEncryptedFilesDir();
-    }
-
-    @Override
     public File getNoBackupFilesDir() {
         return mBase.getNoBackupFilesDir();
     }
@@ -549,6 +536,13 @@
         mBase.sendStickyBroadcastAsUser(intent, user);
     }
 
+    /** @hide */
+    @Override
+    @Deprecated
+    public void sendStickyBroadcastAsUser(Intent intent, UserHandle user, Bundle options) {
+        mBase.sendStickyBroadcastAsUser(intent, user, options);
+    }
+
     @Override
     @Deprecated
     public void sendStickyOrderedBroadcastAsUser(Intent intent,
@@ -803,4 +797,28 @@
     public DisplayAdjustments getDisplayAdjustments(int displayId) {
         return mBase.getDisplayAdjustments(displayId);
     }
+
+    @Override
+    public Context createDeviceEncryptedStorageContext() {
+        return mBase.createDeviceEncryptedStorageContext();
+    }
+
+    /** {@hide} */
+    @SystemApi
+    @Override
+    public Context createCredentialEncryptedStorageContext() {
+        return mBase.createCredentialEncryptedStorageContext();
+    }
+
+    @Override
+    public boolean isDeviceEncryptedStorage() {
+        return mBase.isDeviceEncryptedStorage();
+    }
+
+    /** {@hide} */
+    @SystemApi
+    @Override
+    public boolean isCredentialEncryptedStorage() {
+        return mBase.isCredentialEncryptedStorage();
+    }
 }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index b65d825..a27d1cb 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2991,6 +2991,28 @@
             "android.intent.action.MANAGED_PROFILE_REMOVED";
 
     /**
+     * Broadcast sent to the primary user when an associated managed profile's availability has
+     * changed. This includes when the user toggles the profile's quiet mode, or when the profile
+     * owner suspends the profile. Carries an extra {@link #EXTRA_USER} that specifies the
+     * UserHandle of the profile. When quiet mode is changed, this broadcast will carry a boolean
+     * extra {@link #EXTRA_QUIET_MODE} indicating the new state of quiet mode. This is only sent to
+     * registered receivers, not manifest receivers.
+     */
+    public static final String ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED =
+            "android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED";
+
+    /**
+     * Broadcast sent to the managed profile when its availability has changed. This includes when
+     * the user toggles the profile's quiet mode, or when the profile owner suspends the profile.
+     * When quiet mode is changed, this broadcast will carry a boolean extra
+     * {@link #EXTRA_QUIET_MODE} indicating the new state of quiet mode. This is only sent to
+     * registered receivers, not manifest receivers. See also
+     * {@link #ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED}
+     */
+    public static final String ACTION_AVAILABILITY_CHANGED =
+            "android.intent.action.AVAILABILITY_CHANGED";
+
+    /**
      * Sent when the user taps on the clock widget in the system's "quick settings" area.
      */
     public static final String ACTION_QUICK_CLOCK =
@@ -4028,6 +4050,10 @@
     /** {@hide} */
     public static final String EXTRA_INDEX = "android.intent.extra.INDEX";
 
+    /**
+     * Optional boolean extra indicating whether quiet mode has been switched on or off.
+     */
+    public static final String EXTRA_QUIET_MODE = "android.intent.extra.QUIET_MODE";
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // Intent flags (see mFlags variable).
@@ -4445,6 +4471,22 @@
      * @hide
      */
     public static final int FLAG_RECEIVER_BOOT_UPGRADE = 0x02000000;
+    /**
+     * If set, the broadcast will always go to manifest receivers in background (cached
+     * or not running) apps, regardless of whether that would be done by default.  By
+     * default they will only receive broadcasts if the broadcast has specified an
+     * explicit component or package name.
+     * @hide
+     */
+    public static final int FLAG_RECEIVER_INCLUDE_BACKGROUND = 0x01000000;
+    /**
+     * If set, the broadcast will never go to manifest receivers in background (cached
+     * or not running) apps, regardless of whether that would be done by default.  By
+     * default they will receive broadcasts if the broadcast has specified an
+     * explicit component or package name.
+     * @hide
+     */
+    public static final int FLAG_RECEIVER_EXCLUDE_BACKGROUND = 0x00800000;
 
     /**
      * @hide Flags that can't be changed with PendingIntent.
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 4a3c59b..0cb0e9f 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -756,13 +756,20 @@
     }
 
     public void dump(Printer pw, String prefix) {
+        dump(pw, prefix, DUMP_FLAG_ALL);
+    }
+
+    /** @hide */
+    public void dump(Printer pw, String prefix, int flags) {
         super.dumpFront(pw, prefix);
         if (permission != null) {
             pw.println(prefix + "permission=" + permission);
         }
-        pw.println(prefix + "taskAffinity=" + taskAffinity
-                + " targetActivity=" + targetActivity
-                + " persistableMode=" + persistableModeToString());
+        if ((flags&DUMP_FLAG_DETAILS) != 0) {
+            pw.println(prefix + "taskAffinity=" + taskAffinity
+                    + " targetActivity=" + targetActivity
+                    + " persistableMode=" + persistableModeToString());
+        }
         if (launchMode != 0 || flags != 0 || theme != 0) {
             pw.println(prefix + "launchMode=" + launchMode
                     + " flags=0x" + Integer.toHexString(flags)
@@ -777,14 +784,17 @@
         if (uiOptions != 0) {
             pw.println(prefix + " uiOptions=0x" + Integer.toHexString(uiOptions));
         }
-        pw.println(prefix + "resizeable=" + resizeable + " supportsPip=" + supportsPip);
-        pw.println(prefix + "lockTaskLaunchMode=" + lockTaskLaunchModeToString(lockTaskLaunchMode));
+        if ((flags&DUMP_FLAG_DETAILS) != 0) {
+            pw.println(prefix + "resizeable=" + resizeable + " supportsPip=" + supportsPip);
+            pw.println(prefix + "lockTaskLaunchMode="
+                    + lockTaskLaunchModeToString(lockTaskLaunchMode));
+        }
         if (layout != null) {
             pw.println(prefix + "initialLayout=" + layout.width + "|"
                     + layout.widthFraction + ", " + layout.height + "|"
                     + layout.heightFraction + ", " + layout.gravity);
         }
-        super.dumpBack(pw, prefix);
+        super.dumpBack(pw, prefix, flags);
     }
 
     public String toString() {
diff --git a/core/java/android/content/pm/ApplicationInfo.aidl b/core/java/android/content/pm/ApplicationInfo.aidl
index 006d1bd..59b0a89 100644
--- a/core/java/android/content/pm/ApplicationInfo.aidl
+++ b/core/java/android/content/pm/ApplicationInfo.aidl
@@ -1,17 +1,17 @@
-/* //device/java/android/android/view/WindowManager.aidl
+/*
 **
 ** Copyright 2007, The Android Open Source Project
 **
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
 **
-**     http://www.apache.org/licenses/LICENSE-2.0 
+**     http://www.apache.org/licenses/LICENSE-2.0
 **
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 545478c..0633bff 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -22,7 +22,6 @@
 import android.os.Environment;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.storage.StorageManager;
 import android.text.TextUtils;
@@ -383,13 +382,6 @@
     public static final int FLAG_HARDWARE_ACCELERATED = 1<<29;
 
     /**
-     * Value for {@link #flags}: {@code true} if the application is blocked via restrictions
-     * and for most purposes is considered as not installed.
-     * {@hide}
-     */
-    public static final int FLAG_EPHEMERAL = 1<<30;
-
-    /**
      * Value for {@link #flags}: true if code from this application will need to be
      * loaded into other applications' processes. On devices that support multiple
      * instruction sets, this implies the code might be loaded into a process that's
@@ -462,8 +454,8 @@
     public static final int PRIVATE_FLAG_PRIVILEGED = 1<<3;
 
     /**
-     * Value for {@link #flags}: {@code true} if the application has any IntentFiler with some
-     * data URI using HTTP or HTTPS with an associated VIEW action.
+     * Value for {@link #privateFlags}: {@code true} if the application has any IntentFiler
+     * with some data URI using HTTP or HTTPS with an associated VIEW action.
      *
      * {@hide}
      */
@@ -494,6 +486,13 @@
     public static final int PRIVATE_FLAG_AUTOPLAY = 1 << 7;
 
     /**
+     * Value for {@link #flags}: {@code true} if the application is blocked via restrictions
+     * and for most purposes is considered as not installed.
+     * {@hide}
+     */
+    public static final int PRIVATE_FLAG_EPHEMERAL = 1<<8;
+
+    /**
      * When set, at least one component inside this application is encryption aware.
      *
      * @hide
@@ -591,13 +590,21 @@
     public String[] sharedLibraryFiles;
     
     /**
-     * Full path to a directory assigned to the package for its persistent data.
+     * Full path to the default directory assigned to the package for its
+     * persistent data.
      */
     public String dataDir;
 
-    /** {@hide} */
+    /**
+     * Full path to the device-encrypted directory assigned to the package for
+     * its persistent data.
+     */
     public String deviceEncryptedDataDir;
-    /** {@hide} */
+
+    /**
+     * Full path to the credential-encrypted directory assigned to the package
+     * for its persistent data.
+     */
     public String credentialEncryptedDataDir;
 
     /**
@@ -703,21 +710,30 @@
     public int installLocation = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
 
     public void dump(Printer pw, String prefix) {
+        dump(pw, prefix, DUMP_FLAG_ALL);
+    }
+
+    /** @hide */
+    public void dump(Printer pw, String prefix, int flags) {
         super.dumpFront(pw, prefix);
-        if (className != null) {
+        if ((flags&DUMP_FLAG_DETAILS) != 0 && className != null) {
             pw.println(prefix + "className=" + className);
         }
         if (permission != null) {
             pw.println(prefix + "permission=" + permission);
         }
         pw.println(prefix + "processName=" + processName);
-        pw.println(prefix + "taskAffinity=" + taskAffinity);
+        if ((flags&DUMP_FLAG_DETAILS) != 0) {
+            pw.println(prefix + "taskAffinity=" + taskAffinity);
+        }
         pw.println(prefix + "uid=" + uid + " flags=0x" + Integer.toHexString(flags)
                 + " privateFlags=0x" + Integer.toHexString(privateFlags)
                 + " theme=0x" + Integer.toHexString(theme));
-        pw.println(prefix + "requiresSmallestWidthDp=" + requiresSmallestWidthDp
-                + " compatibleWidthLimitDp=" + compatibleWidthLimitDp
-                + " largestWidthLimitDp=" + largestWidthLimitDp);
+        if ((flags&DUMP_FLAG_DETAILS) != 0) {
+            pw.println(prefix + "requiresSmallestWidthDp=" + requiresSmallestWidthDp
+                    + " compatibleWidthLimitDp=" + compatibleWidthLimitDp
+                    + " largestWidthLimitDp=" + largestWidthLimitDp);
+        }
         pw.println(prefix + "sourceDir=" + sourceDir);
         if (!Objects.equals(sourceDir, publicSourceDir)) {
             pw.println(prefix + "publicSourceDir=" + publicSourceDir);
@@ -732,31 +748,36 @@
         if (resourceDirs != null) {
             pw.println(prefix + "resourceDirs=" + resourceDirs);
         }
-        if (seinfo != null) {
+        if ((flags&DUMP_FLAG_DETAILS) != 0 && seinfo != null) {
             pw.println(prefix + "seinfo=" + seinfo);
         }
         pw.println(prefix + "dataDir=" + dataDir);
-        pw.println(prefix + "deviceEncryptedDataDir=" + deviceEncryptedDataDir);
-        pw.println(prefix + "credentialEncryptedDataDir=" + credentialEncryptedDataDir);
-        if (sharedLibraryFiles != null) {
-            pw.println(prefix + "sharedLibraryFiles=" + Arrays.toString(sharedLibraryFiles));
+        if ((flags&DUMP_FLAG_DETAILS) != 0) {
+            pw.println(prefix + "deviceEncryptedDataDir=" + deviceEncryptedDataDir);
+            pw.println(prefix + "credentialEncryptedDataDir=" + credentialEncryptedDataDir);
+            if (sharedLibraryFiles != null) {
+                pw.println(prefix + "sharedLibraryFiles=" + Arrays.toString(sharedLibraryFiles));
+            }
         }
         pw.println(prefix + "enabled=" + enabled + " targetSdkVersion=" + targetSdkVersion
                 + " versionCode=" + versionCode);
-        if (manageSpaceActivityName != null) {
-            pw.println(prefix + "manageSpaceActivityName="+manageSpaceActivityName);
-        }
-        if (descriptionRes != 0) {
-            pw.println(prefix + "description=0x"+Integer.toHexString(descriptionRes));
-        }
-        if (uiOptions != 0) {
-            pw.println(prefix + "uiOptions=0x" + Integer.toHexString(uiOptions));
-        }
-        pw.println(prefix + "supportsRtl=" + (hasRtlSupport() ? "true" : "false"));
-        if (fullBackupContent > 0) {
-            pw.println(prefix + "fullBackupContent=@xml/" + fullBackupContent);
-        } else {
-            pw.println(prefix + "fullBackupContent=" + (fullBackupContent < 0 ? "false" : "true"));
+        if ((flags&DUMP_FLAG_DETAILS) != 0) {
+            if (manageSpaceActivityName != null) {
+                pw.println(prefix + "manageSpaceActivityName=" + manageSpaceActivityName);
+            }
+            if (descriptionRes != 0) {
+                pw.println(prefix + "description=0x" + Integer.toHexString(descriptionRes));
+            }
+            if (uiOptions != 0) {
+                pw.println(prefix + "uiOptions=0x" + Integer.toHexString(uiOptions));
+            }
+            pw.println(prefix + "supportsRtl=" + (hasRtlSupport() ? "true" : "false"));
+            if (fullBackupContent > 0) {
+                pw.println(prefix + "fullBackupContent=@xml/" + fullBackupContent);
+            } else {
+                pw.println(prefix + "fullBackupContent="
+                        + (fullBackupContent < 0 ? "false" : "true"));
+            }
         }
         super.dumpBack(pw, prefix);
     }
@@ -1083,6 +1104,13 @@
     /**
      * @hide
      */
+    public boolean isEphemeralApp() {
+        return (privateFlags & ApplicationInfo.PRIVATE_FLAG_EPHEMERAL) != 0;
+    }
+
+    /**
+     * @hide
+     */
     @Override protected ApplicationInfo getApplicationInfo() {
         return this;
     }
diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java
index ad7ebe5..a295cc5 100644
--- a/core/java/android/content/pm/ComponentInfo.java
+++ b/core/java/android/content/pm/ComponentInfo.java
@@ -150,23 +150,32 @@
 
     protected void dumpFront(Printer pw, String prefix) {
         super.dumpFront(pw, prefix);
+        if (processName != null && !packageName.equals(processName)) {
+            pw.println(prefix + "processName=" + processName);
+        }
         pw.println(prefix + "enabled=" + enabled + " exported=" + exported
-                + " encryptionAware=" + encryptionAware + " processName=" + processName);
+                + " encryptionAware=" + encryptionAware);
         if (descriptionRes != 0) {
             pw.println(prefix + "description=" + descriptionRes);
         }
     }
-    
+
     protected void dumpBack(Printer pw, String prefix) {
-        if (applicationInfo != null) {
-            pw.println(prefix + "ApplicationInfo:");
-            applicationInfo.dump(pw, prefix + "  ");
-        } else {
-            pw.println(prefix + "ApplicationInfo: null");
+        dumpBack(pw, prefix, DUMP_FLAG_ALL);
+    }
+    
+    void dumpBack(Printer pw, String prefix, int flags) {
+        if ((flags&DUMP_FLAG_APPLICATION) != 0) {
+            if (applicationInfo != null) {
+                pw.println(prefix + "ApplicationInfo:");
+                applicationInfo.dump(pw, prefix + "  ", flags);
+            } else {
+                pw.println(prefix + "ApplicationInfo: null");
+            }
         }
         super.dumpBack(pw, prefix);
     }
-    
+
     public void writeToParcel(Parcel dest, int parcelableFlags) {
         super.writeToParcel(dest, parcelableFlags);
         if ((parcelableFlags & Parcelable.PARCELABLE_ELIDE_DUPLICATES) != 0) {
diff --git a/core/java/android/content/pm/EphemeralApplicationInfo.aidl b/core/java/android/content/pm/EphemeralApplicationInfo.aidl
new file mode 100644
index 0000000..5aaae78
--- /dev/null
+++ b/core/java/android/content/pm/EphemeralApplicationInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.content.pm;
+
+parcelable EphemeralApplicationInfo;
diff --git a/core/java/android/content/pm/EphemeralApplicationInfo.java b/core/java/android/content/pm/EphemeralApplicationInfo.java
new file mode 100644
index 0000000..87663f1
--- /dev/null
+++ b/core/java/android/content/pm/EphemeralApplicationInfo.java
@@ -0,0 +1,120 @@
+/*
+ * 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.content.pm;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.graphics.drawable.Drawable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * This class represents the state of an ephemeral app.
+ *
+ * @hide
+ */
+public final class EphemeralApplicationInfo implements Parcelable {
+    private final ApplicationInfo mApplicationInfo;
+
+    private final String mPackageName;
+    private final CharSequence mLabelText;
+
+    private final String[] mRequestedPermissions;
+    private final String[] mGrantedPermissions;
+
+    public EphemeralApplicationInfo(ApplicationInfo appInfo,
+            String[] requestedPermissions, String[] grantedPermissions) {
+        mApplicationInfo = appInfo;
+        mPackageName = null;
+        mLabelText = null;
+        mRequestedPermissions = requestedPermissions;
+        mGrantedPermissions = grantedPermissions;
+    }
+
+    public EphemeralApplicationInfo(String packageName, CharSequence label,
+            String[] requestedPermissions, String[] grantedPermissions) {
+        mApplicationInfo = null;
+        mPackageName = packageName;
+        mLabelText = label;
+        mRequestedPermissions = requestedPermissions;
+        mGrantedPermissions = grantedPermissions;
+    }
+
+    private EphemeralApplicationInfo(Parcel parcel) {
+        mPackageName = parcel.readString();
+        mLabelText = parcel.readCharSequence();
+        mRequestedPermissions = parcel.readStringArray();
+        mGrantedPermissions = parcel.createStringArray();
+        mApplicationInfo = parcel.readParcelable(null);
+    }
+
+    public @NonNull String getPackageName() {
+        if (mApplicationInfo != null) {
+            return mApplicationInfo.packageName;
+        }
+        return mPackageName;
+    }
+
+    public @NonNull CharSequence loadLabel(@NonNull PackageManager packageManager) {
+        if (mApplicationInfo != null) {
+            return mApplicationInfo.loadLabel(packageManager);
+        }
+        return mLabelText;
+    }
+
+    public @NonNull Drawable loadIcon(@NonNull PackageManager packageManager) {
+        if (mApplicationInfo != null) {
+            return mApplicationInfo.loadIcon(packageManager);
+        }
+        return packageManager.getEphemeralApplicationIcon(mPackageName);
+    }
+
+    public @Nullable String[] getRequestedPermissions() {
+        return mRequestedPermissions;
+    }
+
+    public @Nullable String[] getGrantedPermissions() {
+        return mGrantedPermissions;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeString(mPackageName);
+        parcel.writeCharSequence(mLabelText);
+        parcel.writeStringArray(mRequestedPermissions);
+        parcel.writeStringArray(mGrantedPermissions);
+        parcel.writeParcelable(mApplicationInfo, flags);
+    }
+
+    public static final Creator<EphemeralApplicationInfo> CREATOR =
+            new Creator<EphemeralApplicationInfo>() {
+        @Override
+        public EphemeralApplicationInfo createFromParcel(Parcel parcel) {
+            return new EphemeralApplicationInfo(parcel);
+        }
+
+        @Override
+        public EphemeralApplicationInfo[] newArray(int size) {
+            return new EphemeralApplicationInfo[0];
+        }
+    };
+}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index b9a42eb..b947a2b 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -23,6 +23,7 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ContainerEncryptionParams;
+import android.content.pm.EphemeralApplicationInfo;
 import android.content.pm.FeatureInfo;
 import android.content.pm.IPackageInstallObserver2;
 import android.content.pm.IPackageInstaller;
@@ -47,6 +48,7 @@
 import android.content.pm.UserInfo;
 import android.content.pm.VerificationParams;
 import android.content.pm.VerifierDeviceIdentity;
+import android.graphics.Bitmap;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
@@ -513,4 +515,10 @@
     boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId);
 
     String getPermissionControllerPackageName();
+
+    ParceledListSlice getEphemeralApplications(int userId);
+    byte[] getEphemeralApplicationCookie(String packageName, int userId);
+    boolean setEphemeralApplicationCookie(String packageName, in byte[] cookie, int userId);
+    Bitmap getEphemeralApplicationIcon(String packageName, int userId);
+    boolean isEphemeralApplication(String packageName, int userId);
 }
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index 22a899c..4df83036 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -282,6 +282,21 @@
         return null;
     }
 
+    /**
+     * @hide Flag for dumping: include all details.
+     */
+    public static final int DUMP_FLAG_DETAILS = 1<<0;
+
+    /**
+     * @hide Flag for dumping: include nested ApplicationInfo.
+     */
+    public static final int DUMP_FLAG_APPLICATION = 1<<1;
+
+    /**
+     * @hide Flag for dumping: all flags to dump everything.
+     */
+    public static final int DUMP_FLAG_ALL = DUMP_FLAG_DETAILS | DUMP_FLAG_APPLICATION;
+
     protected void dumpFront(Printer pw, String prefix) {
         if (name != null) {
             pw.println(prefix + "name=" + name);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 9b80a16..a822150 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -47,8 +47,10 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.storage.VolumeInfo;
+import android.provider.Settings;
 import android.util.AndroidException;
 
+import android.util.Log;
 import com.android.internal.util.ArrayUtils;
 
 import java.io.File;
@@ -2860,6 +2862,83 @@
     public abstract List<ApplicationInfo> getInstalledApplications(int flags);
 
     /**
+     * Gets the ephemeral applications the user recently used. Requires
+     * holding "android.permission.ACCESS_EPHEMERAL_APPS".
+     *
+     * @return The ephemeral app list.
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS)
+    public abstract List<EphemeralApplicationInfo> getEphemeralApplications();
+
+    /**
+     * Gets the icon for an ephemeral application.
+     *
+     * @param packageName The app package name.
+     *
+     * @hide
+     */
+    public abstract Drawable getEphemeralApplicationIcon(String packageName);
+
+    /**
+     * Gets whether the caller is an ephemeral app.
+     *
+     * @return Whether caller is an ephemeral app.
+     *
+     * @see #setEphemeralCookie(byte[])
+     * @see #getEphemeralCookie()
+     * @see #getEphemeralCookieMaxSizeBytes()
+     */
+    public abstract boolean isEphemeralApplication();
+
+    /**
+     * Gets the maximum size in bytes of the cookie data an ephemeral app
+     * can store on the device.
+     *
+     * @return The max cookie size in bytes.
+     *
+     * @see #isEphemeralApplication()
+     * @see #setEphemeralCookie(byte[])
+     * @see #getEphemeralCookie()
+     */
+    public abstract int getEphemeralCookieMaxSizeBytes();
+
+    /**
+     * Gets the ephemeral application cookie for this app. Non
+     * ephemeral apps and apps that were ephemeral but were upgraded
+     * to non-ephemeral can still access this API. For ephemeral apps
+     * this cooke is cached for some time after uninstall while for
+     * normal apps the cookie is deleted after the app is uninstalled.
+     * The cookie is always present while the app is installed.
+     *
+     * @return The cookie.
+     *
+     * @see #isEphemeralApplication()
+     * @see #setEphemeralCookie(byte[])
+     * @see #getEphemeralCookieMaxSizeBytes()
+     */
+    public abstract @NonNull byte[] getEphemeralCookie();
+
+    /**
+     * Sets the ephemeral application cookie for the calling app. Non
+     * ephemeral apps and apps that were ephemeral but were upgraded
+     * to non-ephemeral can still access this API. For ephemeral apps
+     * this cooke is cached for some time after uninstall while for
+     * normal apps the cookie is deleted after the app is uninstalled.
+     * The cookie is always present while the app is installed. The
+     * cookie size is limited by {@link #getEphemeralCookieMaxSizeBytes()}.
+     *
+     * @param cookie The cookie data.
+     * @return True if the cookie was set.
+     *
+     * @see #isEphemeralApplication()
+     * @see #getEphemeralCookieMaxSizeBytes()
+     * @see #getEphemeralCookie();
+     */
+    public abstract boolean setEphemeralCookie(@NonNull  byte[] cookie);
+
+    /**
      * Get a list of shared libraries that are available on the
      * system.
      *
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 0307108..b79b6b6 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1470,6 +1470,10 @@
             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
         }
 
+        if ((flags & PARSE_IS_EPHEMERAL) != 0) {
+            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_EPHEMERAL;
+        }
+
         // Resource boolean are -1, so 1 means we don't know the value.
         int supportsSmallScreens = 1;
         int supportsNormalScreens = 1;
diff --git a/core/java/android/content/pm/ProviderInfo.java b/core/java/android/content/pm/ProviderInfo.java
index f6ea058..7e7b32f 100644
--- a/core/java/android/content/pm/ProviderInfo.java
+++ b/core/java/android/content/pm/ProviderInfo.java
@@ -115,9 +115,15 @@
     }
 
     public void dump(Printer pw, String prefix) {
+        dump(pw, prefix, DUMP_FLAG_ALL);
+    }
+
+    /** @hide */
+    public void dump(Printer pw, String prefix, int flags) {
         super.dumpFront(pw, prefix);
         pw.println(prefix + "authority=" + authority);
         pw.println(prefix + "flags=0x" + Integer.toHexString(flags));
+        super.dumpBack(pw, prefix, flags);
     }
 
     public int describeContents() {
diff --git a/core/java/android/content/pm/ResolveInfo.java b/core/java/android/content/pm/ResolveInfo.java
index 7bab35c..a5fb451 100644
--- a/core/java/android/content/pm/ResolveInfo.java
+++ b/core/java/android/content/pm/ResolveInfo.java
@@ -260,6 +260,11 @@
     }
 
     public void dump(Printer pw, String prefix) {
+        dump(pw, prefix, PackageItemInfo.DUMP_FLAG_ALL);
+    }
+
+    /** @hide */
+    public void dump(Printer pw, String prefix, int flags) {
         if (filter != null) {
             pw.println(prefix + "Filter:");
             filter.dump(pw, prefix + "  ");
@@ -279,16 +284,16 @@
         }
         if (activityInfo != null) {
             pw.println(prefix + "ActivityInfo:");
-            activityInfo.dump(pw, prefix + "  ");
+            activityInfo.dump(pw, prefix + "  ", flags);
         } else if (serviceInfo != null) {
             pw.println(prefix + "ServiceInfo:");
-            serviceInfo.dump(pw, prefix + "  ");
+            serviceInfo.dump(pw, prefix + "  ", flags);
         } else if (providerInfo != null) {
             pw.println(prefix + "ProviderInfo:");
-            providerInfo.dump(pw, prefix + "  ");
+            providerInfo.dump(pw, prefix + "  ", flags);
         }
     }
-    
+
     public ResolveInfo() {
         targetUserId = UserHandle.USER_CURRENT;
     }
diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java
index 796c2a4..74e5c2a 100644
--- a/core/java/android/content/pm/ServiceInfo.java
+++ b/core/java/android/content/pm/ServiceInfo.java
@@ -74,9 +74,15 @@
     }
 
     public void dump(Printer pw, String prefix) {
+        dump(pw, prefix, DUMP_FLAG_ALL);
+    }
+
+    /** @hide */
+    void dump(Printer pw, String prefix, int flags) {
         super.dumpFront(pw, prefix);
         pw.println(prefix + "permission=" + permission);
         pw.println(prefix + "flags=0x" + Integer.toHexString(flags));
+        super.dumpBack(pw, prefix, flags);
     }
     
     public String toString() {
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index d7c2215..e3050fe 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -76,6 +76,13 @@
      */
     public static final int FLAG_DISABLED = 0x00000040;
 
+    public static final int FLAG_QUIET_MODE = 0x00000080;
+
+    /**
+     * Indicates that this user is ephemeral. I.e. the user will be removed after leaving
+     * the foreground.
+     */
+    public static final int FLAG_EPHEMERAL = 0x00000100;
 
     public static final int NO_PROFILE_GROUP_ID = UserHandle.USER_NULL;
 
@@ -130,6 +137,14 @@
         return (flags & FLAG_DISABLED) != FLAG_DISABLED;
     }
 
+    public boolean isQuietModeEnabled() {
+        return (flags & FLAG_QUIET_MODE) == FLAG_QUIET_MODE;
+    }
+
+    public boolean isEphemeral() {
+        return (flags & FLAG_EPHEMERAL) == FLAG_EPHEMERAL;
+    }
+
     /**
      * Returns true if the user is a split system user.
      * <p>If {@link UserManager#isSplitSystemUser split system user mode} is not enabled,
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 1a19a58..7db5a08 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -724,9 +724,7 @@
         fontScale = o.fontScale;
         mcc = o.mcc;
         mnc = o.mnc;
-        if (o.locale != null) {
-            locale = (Locale) o.locale.clone();
-        }
+        locale = o.locale == null ? null : (Locale) o.locale.clone();
         o.fixUpLocaleList();
         mLocaleList = o.mLocaleList;
         userSetLocale = o.userSetLocale;
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 7b3dde4..cdca869 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -1988,7 +1988,7 @@
         }
         synchronized (sSync) {
             if (mPluralRule != null) {
-                mPluralRule = PluralRules.forLocale(config.getLocales().getPrimary());
+                mPluralRule = PluralRules.forLocale(mConfiguration.getLocales().getPrimary());
             }
         }
     }
@@ -2421,75 +2421,93 @@
 
     @Nullable
     Drawable loadDrawable(TypedValue value, int id, Theme theme) throws NotFoundException {
-        if (TRACE_FOR_PRELOAD) {
-            // Log only framework resources
-            if ((id >>> 24) == 0x1) {
-                final String name = getResourceName(id);
-                if (name != null) {
-                    Log.d("PreloadDrawable", name);
+        try {
+            if (TRACE_FOR_PRELOAD) {
+                // Log only framework resources
+                if ((id >>> 24) == 0x1) {
+                    final String name = getResourceName(id);
+                    if (name != null) {
+                        Log.d("PreloadDrawable", name);
+                    }
                 }
             }
-        }
 
-        final boolean isColorDrawable;
-        final DrawableCache caches;
-        final long key;
-        if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT
-                && value.type <= TypedValue.TYPE_LAST_COLOR_INT) {
-            isColorDrawable = true;
-            caches = mColorDrawableCache;
-            key = value.data;
-        } else {
-            isColorDrawable = false;
-            caches = mDrawableCache;
-            key = (((long) value.assetCookie) << 32) | value.data;
-        }
-
-        // First, check whether we have a cached version of this drawable
-        // that was inflated against the specified theme.
-        if (!mPreloading) {
-            final Drawable cachedDrawable = caches.getInstance(key, theme);
-            if (cachedDrawable != null) {
-                return cachedDrawable;
+            final boolean isColorDrawable;
+            final DrawableCache caches;
+            final long key;
+            if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT
+                    && value.type <= TypedValue.TYPE_LAST_COLOR_INT) {
+                isColorDrawable = true;
+                caches = mColorDrawableCache;
+                key = value.data;
+            } else {
+                isColorDrawable = false;
+                caches = mDrawableCache;
+                key = (((long) value.assetCookie) << 32) | value.data;
             }
-        }
 
-        // Next, check preloaded drawables. These may contain unresolved theme
-        // attributes.
-        final ConstantState cs;
-        if (isColorDrawable) {
-            cs = sPreloadedColorDrawables.get(key);
-        } else {
-            cs = sPreloadedDrawables[mConfiguration.getLayoutDirection()].get(key);
-        }
+            // First, check whether we have a cached version of this drawable
+            // that was inflated against the specified theme.
+            if (!mPreloading) {
+                final Drawable cachedDrawable = caches.getInstance(key, theme);
+                if (cachedDrawable != null) {
+                    return cachedDrawable;
+                }
+            }
 
-        Drawable dr;
-        if (cs != null) {
-            dr = cs.newDrawable(this);
-        } else if (isColorDrawable) {
-            dr = new ColorDrawable(value.data);
-        } else {
-            dr = loadDrawableForCookie(value, id, null);
-        }
+            // Next, check preloaded drawables. These may contain unresolved theme
+            // attributes.
+            final ConstantState cs;
+            if (isColorDrawable) {
+                cs = sPreloadedColorDrawables.get(key);
+            } else {
+                cs = sPreloadedDrawables[mConfiguration.getLayoutDirection()].get(key);
+            }
 
-        // Determine if the drawable has unresolved theme attributes. If it
-        // does, we'll need to apply a theme and store it in a theme-specific
-        // cache.
-        final boolean canApplyTheme = dr != null && dr.canApplyTheme();
-        if (canApplyTheme && theme != null) {
-            dr = dr.mutate();
-            dr.applyTheme(theme);
-            dr.clearMutated();
-        }
+            Drawable dr;
+            if (cs != null) {
+                dr = cs.newDrawable(this);
+            } else if (isColorDrawable) {
+                dr = new ColorDrawable(value.data);
+            } else {
+                dr = loadDrawableForCookie(value, id, null);
+            }
 
-        // If we were able to obtain a drawable, store it in the appropriate
-        // cache: preload, not themed, null theme, or theme-specific.
-        if (dr != null) {
-            dr.setChangingConfigurations(value.changingConfigurations);
-            cacheDrawable(value, isColorDrawable, caches, theme, canApplyTheme, key, dr);
-        }
+            // Determine if the drawable has unresolved theme attributes. If it
+            // does, we'll need to apply a theme and store it in a theme-specific
+            // cache.
+            final boolean canApplyTheme = dr != null && dr.canApplyTheme();
+            if (canApplyTheme && theme != null) {
+                dr = dr.mutate();
+                dr.applyTheme(theme);
+                dr.clearMutated();
+            }
 
-        return dr;
+            // If we were able to obtain a drawable, store it in the appropriate
+            // cache: preload, not themed, null theme, or theme-specific.
+            if (dr != null) {
+                dr.setChangingConfigurations(value.changingConfigurations);
+                cacheDrawable(value, isColorDrawable, caches, theme, canApplyTheme, key, dr);
+            }
+
+            return dr;
+        } catch (Exception e) {
+            String name;
+            try {
+                name = getResourceName(id);
+            } catch (NotFoundException e2) {
+                name = "(missing name)";
+            }
+
+            // The target drawable might fail to load for any number of
+            // reasons, but we always want to include the resource name.
+            // Since the client already expects this method to throw a
+            // NotFoundException, just throw one of those.
+            final NotFoundException nfe = new NotFoundException("Drawable " + name
+                    + " with resource ID #0x" + Integer.toHexString(id), e);
+            nfe.setStackTrace(new StackTraceElement[0]);
+            throw nfe;
+        }
     }
 
     private void cacheDrawable(TypedValue value, boolean isColorDrawable, DrawableCache caches,
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 8a87bff..02d4e59 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -47,6 +47,8 @@
 import java.util.LinkedHashMap;
 import java.util.List;
 
+import static android.system.OsConstants.*;
+
 /**
  * The Camera class is used to set image capture settings, start/stop preview,
  * snap pictures, and retrieve frames for encoding for video.  This class is a
@@ -173,13 +175,6 @@
     private final Object mAutoFocusCallbackLock = new Object();
 
     private static final int NO_ERROR = 0;
-    private static final int EACCESS = -13;
-    private static final int ENODEV = -19;
-    private static final int EBUSY = -16;
-    private static final int EINVAL = -22;
-    private static final int ENOSYS = -38;
-    private static final int EUSERS = -87;
-    private static final int EOPNOTSUPP = -95;
 
     /**
      * Broadcast Action:  A new picture is taken by the camera, and the entry of
@@ -415,30 +410,28 @@
     private Camera(int cameraId, int halVersion) {
         int err = cameraInitVersion(cameraId, halVersion);
         if (checkInitErrors(err)) {
-            switch(err) {
-                case EACCESS:
-                    throw new RuntimeException("Fail to connect to camera service");
-                case ENODEV:
-                    throw new RuntimeException("Camera initialization failed");
-                case ENOSYS:
-                    throw new RuntimeException("Camera initialization failed because some methods"
-                            + " are not implemented");
-                case EOPNOTSUPP:
-                    throw new RuntimeException("Camera initialization failed because the hal"
-                            + " version is not supported by this device");
-                case EINVAL:
-                    throw new RuntimeException("Camera initialization failed because the input"
-                            + " arugments are invalid");
-                case EBUSY:
-                    throw new RuntimeException("Camera initialization failed because the camera"
-                            + " device was already opened");
-                case EUSERS:
-                    throw new RuntimeException("Camera initialization failed because the max"
-                            + " number of camera devices were already opened");
-                default:
-                    // Should never hit this.
-                    throw new RuntimeException("Unknown camera error");
+            if (err == -EACCES) {
+                throw new RuntimeException("Fail to connect to camera service");
+            } else if (err == -ENODEV) {
+                throw new RuntimeException("Camera initialization failed");
+            } else if (err == -ENOSYS) {
+                throw new RuntimeException("Camera initialization failed because some methods"
+                        + " are not implemented");
+            } else if (err == -EOPNOTSUPP) {
+                throw new RuntimeException("Camera initialization failed because the hal"
+                        + " version is not supported by this device");
+            } else if (err == -EINVAL) {
+                throw new RuntimeException("Camera initialization failed because the input"
+                        + " arugments are invalid");
+            } else if (err == -EBUSY) {
+                throw new RuntimeException("Camera initialization failed because the camera"
+                        + " device was already opened");
+            } else if (err == -EUSERS) {
+                throw new RuntimeException("Camera initialization failed because the max"
+                        + " number of camera devices were already opened");
             }
+            // Should never hit this.
+            throw new RuntimeException("Unknown camera error");
         }
     }
 
@@ -490,15 +483,13 @@
     Camera(int cameraId) {
         int err = cameraInitNormal(cameraId);
         if (checkInitErrors(err)) {
-            switch(err) {
-                case EACCESS:
-                    throw new RuntimeException("Fail to connect to camera service");
-                case ENODEV:
-                    throw new RuntimeException("Camera initialization failed");
-                default:
-                    // Should never hit this.
-                    throw new RuntimeException("Unknown camera error");
+            if (err == -EACCES) {
+                throw new RuntimeException("Fail to connect to camera service");
+            } else if (err == -ENODEV) {
+                throw new RuntimeException("Camera initialization failed");
             }
+            // Should never hit this.
+            throw new RuntimeException("Unknown camera error");
         }
     }
 
diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
index 6b8e113..798c941 100644
--- a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
+++ b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
@@ -43,6 +43,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import static android.system.OsConstants.EACCES;
+import static android.system.OsConstants.ENODEV;
+
 /**
  * Compatibility implementation of the Camera2 API binder interface.
  *
@@ -88,6 +91,14 @@
         mSurfaceIdCounter = 0;
     }
 
+    private static int translateErrorsFromCamera1(int errorCode) {
+        if (errorCode == -EACCES) {
+            return CameraBinderDecorator.PERMISSION_DENIED;
+        }
+
+        return errorCode;
+    }
+
     /**
      * Create a separate looper/thread for the camera to run on; open the camera.
      *
@@ -382,7 +393,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot submit request, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         synchronized(mConfigureLock) {
@@ -402,7 +413,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot submit request list, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         synchronized(mConfigureLock) {
@@ -421,7 +432,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot cancel request, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         synchronized(mConfigureLock) {
@@ -442,7 +453,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot begin configure, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         synchronized(mConfigureLock) {
@@ -462,7 +473,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot end configure, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         ArrayList<Surface> surfaces = null;
@@ -490,7 +501,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot delete stream, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         synchronized(mConfigureLock) {
@@ -515,7 +526,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot create stream, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         synchronized(mConfigureLock) {
@@ -552,7 +563,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot create default request, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         CameraMetadataNative template;
@@ -585,7 +596,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot wait until idle, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         synchronized(mConfigureLock) {
@@ -605,7 +616,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot flush, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         synchronized(mConfigureLock) {
@@ -627,7 +638,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot prepare stream, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         // LEGACY doesn't support actual prepare, just signal success right away
@@ -647,7 +658,7 @@
         }
         if (mLegacyDevice.isClosed()) {
             Log.e(TAG, "Cannot tear down stream, device has been closed.");
-            return CameraBinderDecorator.ENODEV;
+            return -ENODEV;
         }
 
         // LEGACY doesn't support actual teardown, so just a no-op
diff --git a/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java b/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java
index 4b7cfbf..4501e81 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java
@@ -19,6 +19,8 @@
 import android.hardware.camera2.utils.CameraBinderDecorator;
 import android.util.AndroidException;
 
+import static android.system.OsConstants.ENODEV;
+
 /**
  * Utility class containing exception handling used solely by the compatibility mode shim.
  */
@@ -51,18 +53,15 @@
      * exceptions.</p>
      *
      * @param errorFlag error to throw as an exception.
-     * @throws {@link BufferQueueAbandonedException} for {@link CameraBinderDecorator#ENODEV}.
+     * @throws {@link BufferQueueAbandonedException} for -ENODEV.
      * @throws {@link UnsupportedOperationException} for an unknown negative error code.
      * @return {@code errorFlag} if the value was non-negative, throws otherwise.
      */
     public static int throwOnError(int errorFlag) throws BufferQueueAbandonedException {
-        switch (errorFlag) {
-            case CameraBinderDecorator.NO_ERROR: {
-                return CameraBinderDecorator.NO_ERROR;
-            }
-            case CameraBinderDecorator.BAD_VALUE: {
-                throw new BufferQueueAbandonedException();
-            }
+        if (errorFlag == CameraBinderDecorator.NO_ERROR) {
+            return CameraBinderDecorator.NO_ERROR;
+        } else if (errorFlag == -ENODEV) {
+            throw new BufferQueueAbandonedException();
         }
 
         if (errorFlag < 0) {
diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
index b8d6960..8be49e8 100644
--- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
@@ -834,6 +834,7 @@
      * <ul>
      * <li>{@link ImageFormat#JPEG JPEG}
      * <li>{@link ImageFormat#RAW_SENSOR RAW16}
+     * <li>{@link ImageFormat#RAW_PRIVATE RAW_PRIVATE}
      * </ul>
      * </p>
      *
@@ -1328,9 +1329,7 @@
         SparseIntArray map = getFormatsMap(output);
         for (int j = 0; j < map.size(); j++) {
             int format = map.keyAt(j);
-            if (format != HAL_PIXEL_FORMAT_RAW_OPAQUE) {
-                formats[i++] = imageFormatToPublic(format);
-            }
+            formats[i++] = imageFormatToPublic(format);
         }
         if (output) {
             for (int j = 0; j < mDepthOutputFormats.size(); j++) {
@@ -1392,9 +1391,6 @@
     private int getPublicFormatCount(boolean output) {
         SparseIntArray formatsMap = getFormatsMap(output);
         int size = formatsMap.size();
-        if (formatsMap.indexOfKey(HAL_PIXEL_FORMAT_RAW_OPAQUE) >= 0) {
-            size -= 1;
-        }
         if (output) {
             size += mDepthOutputFormats.size();
         }
@@ -1603,6 +1599,8 @@
                 return "Y16";
             case ImageFormat.RAW_SENSOR:
                 return "RAW_SENSOR";
+            case ImageFormat.RAW_PRIVATE:
+                return "RAW_PRIVATE";
             case ImageFormat.RAW10:
                 return "RAW10";
             case ImageFormat.DEPTH16:
diff --git a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
index 1aee794..162edc9 100644
--- a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
+++ b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
@@ -22,6 +22,7 @@
 import static android.hardware.camera2.CameraAccessException.CAMERA_ERROR;
 import static android.hardware.camera2.CameraAccessException.MAX_CAMERAS_IN_USE;
 import static android.hardware.camera2.CameraAccessException.CAMERA_DEPRECATED_HAL;
+import static android.system.OsConstants.*;
 
 import android.os.DeadObjectException;
 import android.os.RemoteException;
@@ -37,12 +38,12 @@
 public class CameraBinderDecorator {
 
     public static final int NO_ERROR = 0;
-    public static final int PERMISSION_DENIED = -1;
-    public static final int ALREADY_EXISTS = -17;
-    public static final int BAD_VALUE = -22;
-    public static final int DEAD_OBJECT = -32;
-    public static final int INVALID_OPERATION = -38;
-    public static final int TIMED_OUT = -110;
+    public static final int PERMISSION_DENIED = -EPERM;
+    public static final int ALREADY_EXISTS = -EEXIST;
+    public static final int BAD_VALUE = -EINVAL;
+    public static final int DEAD_OBJECT = -ENOSYS;
+    public static final int INVALID_OPERATION = -EPIPE;
+    public static final int TIMED_OUT = -ETIMEDOUT;
 
     /**
      * TODO: add as error codes in Errors.h
@@ -52,12 +53,6 @@
      * - NOT_SUPPORTED
      * - TOO_MANY_USERS
      */
-    public static final int EACCES = -13;
-    public static final int EBUSY = -16;
-    public static final int ENODEV = -19;
-    public static final int EOPNOTSUPP = -95;
-    public static final int EUSERS = -87;
-
 
     static class CameraBinderDecoratorListener implements Decorator.DecoratorListener {
 
@@ -101,35 +96,34 @@
      * @param errorFlag error to throw as an exception.
      */
     public static void throwOnError(int errorFlag) {
-        switch (errorFlag) {
-            case NO_ERROR:
-                return;
-            case PERMISSION_DENIED:
-                throw new SecurityException("Lacking privileges to access camera service");
-            case ALREADY_EXISTS:
-                // This should be handled at the call site. Typically this isn't bad,
-                // just means we tried to do an operation that already completed.
-                return;
-            case BAD_VALUE:
-                throw new IllegalArgumentException("Bad argument passed to camera service");
-            case DEAD_OBJECT:
-                throw new CameraRuntimeException(CAMERA_DISCONNECTED);
-            case TIMED_OUT:
-                throw new CameraRuntimeException(CAMERA_ERROR,
-                        "Operation timed out in camera service");
-            case EACCES:
-                throw new CameraRuntimeException(CAMERA_DISABLED);
-            case EBUSY:
-                throw new CameraRuntimeException(CAMERA_IN_USE);
-            case EUSERS:
-                throw new CameraRuntimeException(MAX_CAMERAS_IN_USE);
-            case ENODEV:
-                throw new CameraRuntimeException(CAMERA_DISCONNECTED);
-            case EOPNOTSUPP:
-                throw new CameraRuntimeException(CAMERA_DEPRECATED_HAL);
-            case INVALID_OPERATION:
-                throw new CameraRuntimeException(CAMERA_ERROR,
-                        "Illegal state encountered in camera service.");
+        if (errorFlag == NO_ERROR) {
+            return;
+        } else if (errorFlag == PERMISSION_DENIED) {
+            throw new SecurityException("Lacking privileges to access camera service");
+        } else if (errorFlag == ALREADY_EXISTS) {
+            // This should be handled at the call site. Typically this isn't bad,
+            // just means we tried to do an operation that already completed.
+            return;
+        } else if (errorFlag == BAD_VALUE) {
+            throw new IllegalArgumentException("Bad argument passed to camera service");
+        } else if (errorFlag == DEAD_OBJECT) {
+            throw new CameraRuntimeException(CAMERA_DISCONNECTED);
+        } else if (errorFlag == TIMED_OUT) {
+            throw new CameraRuntimeException(CAMERA_ERROR,
+                    "Operation timed out in camera service");
+        } else if (errorFlag == -EACCES) {
+            throw new CameraRuntimeException(CAMERA_DISABLED);
+        } else if (errorFlag == -EBUSY) {
+            throw new CameraRuntimeException(CAMERA_IN_USE);
+        } else if (errorFlag == -EUSERS) {
+            throw new CameraRuntimeException(MAX_CAMERAS_IN_USE);
+        } else if (errorFlag == -ENODEV) {
+            throw new CameraRuntimeException(CAMERA_DISCONNECTED);
+        } else if (errorFlag == -EOPNOTSUPP) {
+            throw new CameraRuntimeException(CAMERA_DEPRECATED_HAL);
+        } else if (errorFlag == INVALID_OPERATION) {
+            throw new CameraRuntimeException(CAMERA_ERROR,
+                    "Illegal state encountered in camera service.");
         }
 
         /**
diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java
index c85e97b..d490409 100644
--- a/core/java/android/hardware/soundtrigger/SoundTrigger.java
+++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java
@@ -25,6 +25,8 @@
 import java.util.Arrays;
 import java.util.UUID;
 
+import static android.system.OsConstants.*;
+
 /**
  * The SoundTrigger class provides access via JNI to the native service managing
  * the sound trigger HAL.
@@ -35,11 +37,11 @@
 
     public static final int STATUS_OK = 0;
     public static final int STATUS_ERROR = Integer.MIN_VALUE;
-    public static final int STATUS_PERMISSION_DENIED = -1;
-    public static final int STATUS_NO_INIT = -19;
-    public static final int STATUS_BAD_VALUE = -22;
-    public static final int STATUS_DEAD_OBJECT = -32;
-    public static final int STATUS_INVALID_OPERATION = -38;
+    public static final int STATUS_PERMISSION_DENIED = -EPERM;
+    public static final int STATUS_NO_INIT = -ENODEV;
+    public static final int STATUS_BAD_VALUE = -EINVAL;
+    public static final int STATUS_DEAD_OBJECT = -EPIPE;
+    public static final int STATUS_INVALID_OPERATION = -ENOSYS;
 
     /*****************************************************************************
      * A ModuleProperties describes a given sound trigger hardware module
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index a23a6cb..1e3bcd0 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
+import android.os.Process;
 import android.os.RemoteException;
 import android.util.Log;
 
@@ -455,6 +456,21 @@
     }
 
     /**
+     * Grants permission for USB device without showing system dialog.
+     * Only system components can call this function.
+     * @param device to request permissions for
+     *
+     * {@hide}
+     */
+    public void grantPermission(UsbDevice device) {
+        try {
+            mService.grantDevicePermission(device, Process.myUid());
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException in grantPermission", e);
+        }
+    }
+
+    /**
      * Returns true if the specified USB function is currently enabled when in device mode.
      * <p>
      * USB functions represent interfaces which are published to the host to access
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index c71d6cc..9ee6228 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -48,12 +48,15 @@
     UserInfo getProfileParent(int userHandle);
     boolean isSameProfileGroup(int userId, int otherUserId);
     UserInfo getUserInfo(int userHandle);
+    String getUserAccount(int userId);
+    void setUserAccount(int userId, String accountName);
     long getUserCreationTime(int userHandle);
     boolean isRestricted();
     boolean canHaveRestrictedProfile(int userId);
     int getUserSerialNumber(int userHandle);
     int getUserHandle(int userSerialNumber);
     Bundle getUserRestrictions(int userHandle);
+    boolean hasBaseUserRestriction(String restrictionKey, int userHandle);
     boolean hasUserRestriction(in String restrictionKey, int userHandle);
     void setUserRestriction(String key, boolean value, int userId);
     void setApplicationRestrictions(in String packageName, in Bundle restrictions,
@@ -63,4 +66,6 @@
     void setDefaultGuestRestrictions(in Bundle restrictions);
     Bundle getDefaultGuestRestrictions();
     boolean markGuestForDeletion(int userHandle);
+    void setQuietModeEnabled(int userHandle, boolean enableQuietMode);
+    boolean isQuietModeEnabled(int userHandle);
 }
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index f2aea08..9b68f90 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -61,12 +61,12 @@
  * appropriate to place any Parcel data in to persistent storage: changes
  * in the underlying implementation of any of the data in the Parcel can
  * render older data unreadable.</p>
- * 
+ *
  * <p>The bulk of the Parcel API revolves around reading and writing data
  * of various types.  There are six major classes of such functions available.</p>
- * 
+ *
  * <h3>Primitives</h3>
- * 
+ *
  * <p>The most basic data functions are for writing and reading primitive
  * data types: {@link #writeByte}, {@link #readByte}, {@link #writeDouble},
  * {@link #readDouble}, {@link #writeFloat}, {@link #readFloat}, {@link #writeInt},
@@ -74,15 +74,15 @@
  * {@link #writeString}, {@link #readString}.  Most other
  * data operations are built on top of these.  The given data is written and
  * read using the endianess of the host CPU.</p>
- * 
+ *
  * <h3>Primitive Arrays</h3>
- * 
+ *
  * <p>There are a variety of methods for reading and writing raw arrays
  * of primitive objects, which generally result in writing a 4-byte length
  * followed by the primitive data items.  The methods for reading can either
  * read the data into an existing array, or create and return a new array.
  * These available types are:</p>
- * 
+ *
  * <ul>
  * <li> {@link #writeBooleanArray(boolean[])},
  * {@link #readBooleanArray(boolean[])}, {@link #createBooleanArray()}
@@ -104,9 +104,9 @@
  * <li> {@link #writeSparseBooleanArray(SparseBooleanArray)},
  * {@link #readSparseBooleanArray()}.
  * </ul>
- * 
+ *
  * <h3>Parcelables</h3>
- * 
+ *
  * <p>The {@link Parcelable} protocol provides an extremely efficient (but
  * low-level) protocol for objects to write and read themselves from Parcels.
  * You can use the direct methods {@link #writeParcelable(Parcelable, int)}
@@ -116,7 +116,7 @@
  * methods write both the class type and its data to the Parcel, allowing
  * that class to be reconstructed from the appropriate class loader when
  * later reading.</p>
- * 
+ *
  * <p>There are also some methods that provide a more efficient way to work
  * with Parcelables: {@link #writeTypedObject}, {@link #writeTypedArray},
  * {@link #writeTypedList}, {@link #readTypedObject},
@@ -129,9 +129,9 @@
  * call {@link Parcelable#writeToParcel Parcelable.writeToParcel} and
  * {@link Parcelable.Creator#createFromParcel Parcelable.Creator.createFromParcel}
  * yourself.)</p>
- * 
+ *
  * <h3>Bundles</h3>
- * 
+ *
  * <p>A special type-safe container, called {@link Bundle}, is available
  * for key/value maps of heterogeneous values.  This has many optimizations
  * for improved performance when reading and writing data, and its type-safe
@@ -139,16 +139,16 @@
  * data contents into a Parcel.  The methods to use are
  * {@link #writeBundle(Bundle)}, {@link #readBundle()}, and
  * {@link #readBundle(ClassLoader)}.
- * 
+ *
  * <h3>Active Objects</h3>
- * 
+ *
  * <p>An unusual feature of Parcel is the ability to read and write active
  * objects.  For these objects the actual contents of the object is not
  * written, rather a special token referencing the object is written.  When
  * reading the object back from the Parcel, you do not get a new instance of
  * the object, but rather a handle that operates on the exact same object that
  * was originally written.  There are two forms of active objects available.</p>
- * 
+ *
  * <p>{@link Binder} objects are a core facility of Android's general cross-process
  * communication system.  The {@link IBinder} interface describes an abstract
  * protocol with a Binder object.  Any such interface can be written in to
@@ -161,7 +161,7 @@
  * {@link #createBinderArray()},
  * {@link #writeBinderList(List)}, {@link #readBinderList(List)},
  * {@link #createBinderArrayList()}.</p>
- * 
+ *
  * <p>FileDescriptor objects, representing raw Linux file descriptor identifiers,
  * can be written and {@link ParcelFileDescriptor} objects returned to operate
  * on the original file descriptor.  The returned file descriptor is a dup
@@ -169,9 +169,9 @@
  * operating on the same underlying file stream, with the same position, etc.
  * The methods to use are {@link #writeFileDescriptor(FileDescriptor)},
  * {@link #readFileDescriptor()}.
- * 
+ *
  * <h3>Untyped Containers</h3>
- * 
+ *
  * <p>A final class of methods are for writing and reading standard Java
  * containers of arbitrary types.  These all revolve around the
  * {@link #writeValue(Object)} and {@link #readValue(ClassLoader)} methods
@@ -233,8 +233,10 @@
     private static final int VAL_PERSISTABLEBUNDLE = 25;
     private static final int VAL_SIZE = 26;
     private static final int VAL_SIZEF = 27;
+    private static final int VAL_DOUBLEARRAY = 28;
 
     // The initial int32 in a Binder call's reply Parcel header:
+    // Keep these in sync with libbinder's binder/Status.h.
     private static final int EX_SECURITY = -1;
     private static final int EX_BAD_PARCELABLE = -2;
     private static final int EX_ILLEGAL_ARGUMENT = -3;
@@ -242,7 +244,11 @@
     private static final int EX_ILLEGAL_STATE = -5;
     private static final int EX_NETWORK_MAIN_THREAD = -6;
     private static final int EX_UNSUPPORTED_OPERATION = -7;
+    private static final int EX_SERVICE_SPECIFIC = -8;
     private static final int EX_HAS_REPLY_HEADER = -128;  // special; see below
+    // EX_TRANSACTION_FAILED is used exclusively in native code.
+    // see libbinder's binder/Status.h
+    private static final int EX_TRANSACTION_FAILED = -129;
 
     private static native int nativeDataSize(long nativePtr);
     private static native int nativeDataAvail(long nativePtr);
@@ -663,7 +669,7 @@
      * growing dataCapacity() if needed.  The Map keys must be String objects.
      * The Map values are written using {@link #writeValue} and must follow
      * the specification there.
-     * 
+     *
      * <p>It is strongly recommended to use {@link #writeBundle} instead of
      * this method, since the Bundle class provides a type-safe API that
      * allows you to avoid mysterious type errors at the point of marshalling.
@@ -1429,6 +1435,9 @@
         } else if (v instanceof SizeF) {
             writeInt(VAL_SIZEF);
             writeSizeF((SizeF) v);
+        } else if (v instanceof double[]) {
+            writeInt(VAL_DOUBLEARRAY);
+            writeDoubleArray((double[]) v);
         } else {
             Class<?> clazz = v.getClass();
             if (clazz.isArray() && clazz.getComponentType() == Object.class) {
@@ -1504,7 +1513,7 @@
      * exception will be re-thrown by this function as a RuntimeException
      * (to be caught by the system's last-resort exception handling when
      * dispatching a transaction).
-     * 
+     *
      * <p>The supported exception types are:
      * <ul>
      * <li>{@link BadParcelableException}
@@ -1514,7 +1523,7 @@
      * <li>{@link SecurityException}
      * <li>{@link NetworkOnMainThreadException}
      * </ul>
-     * 
+     *
      * @param e The Exception to be written.
      *
      * @see #writeNoException
@@ -1536,6 +1545,8 @@
             code = EX_NETWORK_MAIN_THREAD;
         } else if (e instanceof UnsupportedOperationException) {
             code = EX_UNSUPPORTED_OPERATION;
+        } else if (e instanceof ServiceSpecificException) {
+            code = EX_SERVICE_SPECIFIC;
         }
         writeInt(code);
         StrictMode.clearGatheredViolations();
@@ -1546,6 +1557,9 @@
             throw new RuntimeException(e);
         }
         writeString(e.getMessage());
+        if (e instanceof ServiceSpecificException) {
+            writeInt(((ServiceSpecificException)e).errorCode);
+        }
     }
 
     /**
@@ -1656,6 +1670,8 @@
                 throw new NetworkOnMainThreadException();
             case EX_UNSUPPORTED_OPERATION:
                 throw new UnsupportedOperationException(msg);
+            case EX_SERVICE_SPECIFIC:
+                throw new ServiceSpecificException(readInt(), msg);
         }
         throw new RuntimeException("Unknown exception code: " + code
                 + " msg " + msg);
@@ -1835,7 +1851,7 @@
             if (Bundle.DEBUG) Log.d(TAG, "null bundle: length=" + length);
             return null;
         }
-        
+
         final Bundle bundle = new Bundle(this, length);
         if (loader != null) {
             bundle.setClassLoader(loader);
@@ -2346,7 +2362,7 @@
             return readArrayList(loader);
 
         case VAL_BOOLEANARRAY:
-            return createBooleanArray();        
+            return createBooleanArray();
 
         case VAL_BYTEARRAY:
             return createByteArray();
@@ -2396,6 +2412,9 @@
         case VAL_SIZEF:
             return readSizeF();
 
+        case VAL_DOUBLEARRAY:
+            return createDoubleArray();
+
         default:
             int off = dataPosition() - 4;
             throw new RuntimeException(
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 54bfca3..eca2c3b 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -144,6 +144,12 @@
     public static final int SHARED_RELRO_UID = 1037;
 
     /**
+     * Defines the UID/GID for the audioserver process.
+     * @hide
+     */
+    public static final int AUDIOSERVER_UID = 1041;
+
+    /**
      * Defines the start of a range of UIDs (and GIDs), going from this
      * number to {@link #LAST_APPLICATION_UID} that are reserved for assigning
      * to applications.
diff --git a/core/java/android/os/ServiceSpecificException.java b/core/java/android/os/ServiceSpecificException.java
new file mode 100644
index 0000000..20f237a5
--- /dev/null
+++ b/core/java/android/os/ServiceSpecificException.java
@@ -0,0 +1,39 @@
+/*
+ * 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;
+
+/**
+ * An exception specific to a service.
+ *
+ * <p>This exception includes an error code specific to the throwing
+ * service.  This is mostly used by system services to indicate
+ * domain specific error conditions.
+ *
+ * @hide
+ */
+public class ServiceSpecificException extends RuntimeException {
+    public final int errorCode;
+
+    ServiceSpecificException(int errorCode, String message) {
+        super(message);
+        this.errorCode = errorCode;
+    }
+
+    ServiceSpecificException(int errorCode) {
+        this.errorCode = errorCode;
+    }
+}
+
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index c2fc5e4..1f16c4a 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -15,8 +15,10 @@
  */
 package android.os;
 
+import android.Manifest;
 import android.accounts.AccountManager;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
@@ -721,6 +723,25 @@
     }
 
     /**
+     * Checks if the calling app is running as an ephemeral user.
+     *
+     * @return whether the caller is an ephemeral user.
+     * @hide
+     */
+    public boolean isEphemeralUser() {
+        return isUserEphemeral(UserHandle.myUserId());
+    }
+
+    /**
+     * Returns whether the specified user is ephemeral.
+     * @hide
+     */
+    public boolean isUserEphemeral(int userId) {
+        final UserInfo user = getUserInfo(userId);
+        return user != null && user.isEphemeral();
+    }
+
+    /**
      * Return whether the given user is actively running.  This means that
      * the user is in the "started" state, not "stopped" -- it is currently
      * allowed to run code through scheduled alarms, receiving broadcasts,
@@ -755,6 +776,17 @@
     }
 
     /**
+     * Return whether the calling user is running in a "locked" state. A user is
+     * unlocked only after they've entered their credentials (such as a lock
+     * pattern or PIN), and credential-encrypted private app data storage is
+     * available.
+     */
+    @Deprecated
+    public boolean isUserRunningAndLocked() {
+        return isUserRunningAndLocked(Process.myUserHandle());
+    }
+
+    /**
      * Return whether the given user is running in a "locked" state. A user
      * is unlocked only after they've entered their credentials (such as a lock
      * pattern or PIN), and credential-encrypted private app data storage is
@@ -762,6 +794,7 @@
      *
      * @param user to retrieve the unlocked state for.
      */
+    @Deprecated
     public boolean isUserRunningAndLocked(UserHandle user) {
         try {
             return ActivityManagerNative.getDefault().isUserRunning(
@@ -772,6 +805,17 @@
     }
 
     /**
+     * Return whether the calling user is running in an "unlocked" state. A user
+     * is unlocked only after they've entered their credentials (such as a lock
+     * pattern or PIN), and credential-encrypted private app data storage is
+     * available.
+     */
+    @Deprecated
+    public boolean isUserRunningAndUnlocked() {
+        return isUserRunningAndUnlocked(Process.myUserHandle());
+    }
+
+    /**
      * Return whether the given user is running in an "unlocked" state. A user
      * is unlocked only after they've entered their credentials (such as a lock
      * pattern or PIN), and credential-encrypted private app data storage is
@@ -779,6 +823,7 @@
      *
      * @param user to retrieve the unlocked state for.
      */
+    @Deprecated
     public boolean isUserRunningAndUnlocked(UserHandle user) {
         try {
             return ActivityManagerNative.getDefault().isUserRunning(
@@ -789,6 +834,33 @@
     }
 
     /**
+     * Return whether the calling user is running in an "unlocked" state. A user
+     * is unlocked only after they've entered their credentials (such as a lock
+     * pattern or PIN), and credential-encrypted private app data storage is
+     * available.
+     */
+    public boolean isUserUnlocked() {
+        return isUserUnlocked(Process.myUserHandle());
+    }
+
+    /**
+     * Return whether the given user is running in an "unlocked" state. A user
+     * is unlocked only after they've entered their credentials (such as a lock
+     * pattern or PIN), and credential-encrypted private app data storage is
+     * available.
+     *
+     * @param user to retrieve the unlocked state for.
+     */
+    public boolean isUserUnlocked(UserHandle user) {
+        try {
+            return ActivityManagerNative.getDefault().isUserRunning(
+                    user.getIdentifier(), ActivityManager.FLAG_AND_UNLOCKED);
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /**
      * Returns the UserInfo object describing a specific user.
      * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      * @param userHandle the user handle of the user whose information is being requested.
@@ -826,6 +898,24 @@
         }
     }
 
+     /**
+     * @hide
+     * Returns whether the given user has been disallowed from performing certain actions
+     * or setting certain settings through UserManager. This method disregards restrictions
+     * set by device policy.
+     * @param restrictionKey the string key representing the restriction
+     * @param userHandle the UserHandle of the user for whom to retrieve the restrictions.
+     */
+    public boolean hasBaseUserRestriction(String restrictionKey, UserHandle userHandle) {
+        try {
+            return mService.hasBaseUserRestriction(restrictionKey, userHandle.getIdentifier());
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not get base user restrictions for user " +
+                    userHandle.getIdentifier(), re);
+            return false;
+        }
+    }
+
     /**
      * This will no longer work.  Device owners and profile owners should use
      * {@link DevicePolicyManager#addUserRestriction(ComponentName, String)} instead.
@@ -1084,6 +1174,39 @@
     }
 
     /**
+     * @return the user's account name, null if not found.
+     * @hide
+     */
+    @RequiresPermission( allOf = {
+            Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+            Manifest.permission.MANAGE_USERS
+    })
+    public @Nullable String getUserAccount(int userHandle) {
+        try {
+            return mService.getUserAccount(userHandle);
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not get user account", re);
+            return null;
+        }
+    }
+
+    /**
+     * Set account name for the given user.
+     * @hide
+     */
+    @RequiresPermission( allOf = {
+            Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+            Manifest.permission.MANAGE_USERS
+    })
+    public void setUserAccount(int userHandle, @Nullable String accountName) {
+        try {
+            mService.setUserAccount(userHandle, accountName);
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not set user account", re);
+        }
+    }
+
+    /**
      * Returns information for Primary user.
      * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      *
@@ -1246,6 +1369,36 @@
     }
 
     /**
+     * Set quiet mode of a managed profile.
+     *
+     * @param userHandle The user handle of the profile.
+     * @param enableQuietMode Whether quiet mode should be enabled or disabled.
+     * @hide
+     */
+    public void setQuietModeEnabled(int userHandle, boolean enableQuietMode) {
+        try {
+            mService.setQuietModeEnabled(userHandle, enableQuietMode);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Could not change the profile's quiet mode", e);
+        }
+    }
+
+    /**
+     * Returns whether the given profile is in quiet mode or not.
+     *
+     * @param userHandle The user handle of the profile to be queried.
+     * @return true if the profile is in quiet mode, false otherwise.
+     */
+    public boolean isQuietModeEnabled(UserHandle userHandle) {
+        try {
+            return mService.isQuietModeEnabled(userHandle.getIdentifier());
+        } catch (RemoteException e) {
+            Log.w(TAG, "Could not query the profile's quiet mode", e);
+        }
+        return false;
+    }
+
+    /**
      * If the target user is a managed profile of the calling user or the caller
      * is itself a managed profile, then this returns a badged copy of the given
      * icon to be able to distinguish it from the original icon. For badging an
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index c6510f0..9b3f02d 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -25,8 +25,6 @@
 import android.os.Parcelable;
 import android.os.RemoteException;
 
-import java.io.FileDescriptor;
-
 /**
  * WARNING! Update IMountService.h and IMountService.cpp if you change this
  * file. In particular, the ordering of the methods below must match the
@@ -1202,13 +1200,15 @@
             }
 
             @Override
-            public void createUserKey(int userId, int serialNumber) throws RemoteException {
+            public void createUserKey(int userId, int serialNumber, boolean ephemeral)
+                    throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
                 try {
                     _data.writeInterfaceToken(DESCRIPTOR);
                     _data.writeInt(userId);
                     _data.writeInt(serialNumber);
+                    _data.writeInt(ephemeral ? 1 : 0);
                     mRemote.transact(Stub.TRANSACTION_createUserKey, _data, _reply, 0);
                     _reply.readException();
                 } finally {
@@ -1283,7 +1283,8 @@
             }
 
             @Override
-            public void prepareUserStorage(String volumeUuid, int userId, int serialNumber)
+            public void prepareUserStorage(
+                    String volumeUuid, int userId, int serialNumber, boolean ephemeral)
                     throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
@@ -1292,6 +1293,7 @@
                     _data.writeString(volumeUuid);
                     _data.writeInt(userId);
                     _data.writeInt(serialNumber);
+                    _data.writeInt(ephemeral ? 1 : 0);
                     mRemote.transact(Stub.TRANSACTION_prepareUserStorage, _data, _reply, 0);
                     _reply.readException();
                 } finally {
@@ -2012,7 +2014,8 @@
                     data.enforceInterface(DESCRIPTOR);
                     int userId = data.readInt();
                     int serialNumber = data.readInt();
-                    createUserKey(userId, serialNumber);
+                    boolean ephemeral = data.readInt() != 0;
+                    createUserKey(userId, serialNumber, ephemeral);
                     reply.writeNoException();
                     return true;
                 }
@@ -2052,7 +2055,8 @@
                     String volumeUuid = data.readString();
                     int userId = data.readInt();
                     int serialNumber = data.readInt();
-                    prepareUserStorage(volumeUuid, userId, serialNumber);
+                    boolean ephemeral = data.readInt() != 0;
+                    prepareUserStorage(volumeUuid, userId, serialNumber, ephemeral);
                     reply.writeNoException();
                     return true;
                 }
@@ -2376,15 +2380,16 @@
     public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
             throws RemoteException;
 
-    public void createUserKey(int userId, int serialNumber) throws RemoteException;
+    public void createUserKey(int userId, int serialNumber, boolean ephemeral)
+            throws RemoteException;
     public void destroyUserKey(int userId) throws RemoteException;
 
     public void unlockUserKey(int userId, int serialNumber, byte[] token) throws RemoteException;
     public void lockUserKey(int userId) throws RemoteException;
     public boolean isUserKeyUnlocked(int userId) throws RemoteException;
 
-    public void prepareUserStorage(String volumeUuid, int userId, int serialNumber)
-            throws RemoteException;
+    public void prepareUserStorage(String volumeUuid, int userId, int serialNumber,
+            boolean ephemeral) throws RemoteException;
 
     public ParcelFileDescriptor mountAppFuse(String name) throws RemoteException;
 }
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index db12564..beda169 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -966,9 +966,9 @@
     }
 
     /** {@hide} */
-    public void createUserKey(int userId, int serialNumber) {
+    public void createUserKey(int userId, int serialNumber, boolean ephemeral) {
         try {
-            mMountService.createUserKey(userId, serialNumber);
+            mMountService.createUserKey(userId, serialNumber, ephemeral);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
@@ -1002,9 +1002,10 @@
     }
 
     /** {@hide} */
-    public void prepareUserStorage(String volumeUuid, int userId, int serialNumber) {
+    public void prepareUserStorage(
+            String volumeUuid, int userId, int serialNumber, boolean ephemeral) {
         try {
-            mMountService.prepareUserStorage(volumeUuid, userId, serialNumber);
+            mMountService.prepareUserStorage(volumeUuid, userId, serialNumber, ephemeral);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
@@ -1021,8 +1022,17 @@
 
     /** {@hide} */
     public static boolean isFileBasedEncryptionEnabled() {
-        return "file".equals(SystemProperties.get("ro.crypto.type", "none"))
-                || SystemProperties.getBoolean(StorageManager.PROP_EMULATE_FBE, false);
+        return isNativeFileBasedEncryptionEnabled() || isEmulatedFileBasedEncryptionEnabled();
+    }
+
+    /** {@hide} */
+    public static boolean isNativeFileBasedEncryptionEnabled() {
+        return "file".equals(SystemProperties.get("ro.crypto.type", "none"));
+    }
+
+    /** {@hide} */
+    public static boolean isEmulatedFileBasedEncryptionEnabled() {
+        return SystemProperties.getBoolean(StorageManager.PROP_EMULATE_FBE, false);
     }
 
     /** {@hide} */
diff --git a/core/java/android/preference/PreferenceManager.java b/core/java/android/preference/PreferenceManager.java
index 4e4b1c9..fda6326 100644
--- a/core/java/android/preference/PreferenceManager.java
+++ b/core/java/android/preference/PreferenceManager.java
@@ -371,7 +371,13 @@
                 getDefaultSharedPreferencesMode());
     }
 
-    private static String getDefaultSharedPreferencesName(Context context) {
+    /**
+     * Returns the name used for storing default shared preferences.
+     *
+     * @see #getDefaultSharedPreferences(Context)
+     * @see Context#getSharedPreferencesPath(String)
+     */
+    public static String getDefaultSharedPreferencesName(Context context) {
         return context.getPackageName() + "_preferences";
     }
 
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index c0d95a1..10432b5 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -6194,6 +6194,14 @@
                     "filter");
 
             /**
+             * It supports the similar semantics as {@link #CONTENT_FILTER_URI} and returns the same
+             * columns. This URI requires {@link ContactsContract#DIRECTORY_PARAM_KEY} in
+             * parameters, otherwise it will throw UnsupportedOperationException.
+             */
+            public static final Uri ENTERPRISE_CONTENT_FILTER_URI = Uri.withAppendedPath(
+                    CONTENT_URI, "filter_enterprise");
+
+            /**
              * The email address.
              * <P>Type: TEXT</P>
              */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index dad3c67..74fd8cd 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3323,6 +3323,7 @@
             PUBLIC_SETTINGS.add(SOUND_EFFECTS_ENABLED);
             PUBLIC_SETTINGS.add(HAPTIC_FEEDBACK_ENABLED);
             PUBLIC_SETTINGS.add(SHOW_WEB_SUGGESTIONS);
+            PUBLIC_SETTINGS.add(VIBRATE_WHEN_RINGING);
         }
 
         /**
@@ -3344,7 +3345,6 @@
             PRIVATE_SETTINGS.add(VIBRATE_IN_SILENT);
             PRIVATE_SETTINGS.add(MEDIA_BUTTON_RECEIVER);
             PRIVATE_SETTINGS.add(HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY);
-            PRIVATE_SETTINGS.add(VIBRATE_WHEN_RINGING);
             PRIVATE_SETTINGS.add(DTMF_TONE_TYPE_WHEN_DIALING);
             PRIVATE_SETTINGS.add(HEARING_AID);
             PRIVATE_SETTINGS.add(TTY_MODE);
@@ -4912,6 +4912,15 @@
                 "accessibility_display_daltonizer";
 
         /**
+         * Float list that specifies the color matrix to apply to
+         * the display. Valid values are defined in AccessibilityManager.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_DISPLAY_COLOR_MATRIX =
+                "accessibility_display_color_matrix";
+
+        /**
          * Setting that specifies whether automatic click when the mouse pointer stops moving is
          * enabled.
          *
@@ -7792,6 +7801,24 @@
         public static final String LTE_SERVICE_FORCED = "lte_service_forced";
 
         /**
+         * Ephemeral app cookie max size in bytes.
+         * <p>
+         * Type: int
+         * @hide
+         */
+        public static final String EPHEMERAL_COOKIE_MAX_SIZE_BYTES =
+                "ephemeral_cookie_max_size_bytes";
+
+        /**
+         * The duration for caching uninstalled ephemeral apps.
+         * <p>
+         * Type: long
+         * @hide
+         */
+        public static final String UNINSTALLED_EPHEMERAL_APP_CACHE_DURATION_MILLIS =
+                "uninstalled_ephemeral_app_cache_duration_millis";
+
+        /**
          * Settings to backup. This is here so that it's in the same place as the settings
          * keys and easy to update.
          *
diff --git a/core/java/android/security/FrameworkNetworkSecurityPolicy.java b/core/java/android/security/FrameworkNetworkSecurityPolicy.java
new file mode 100644
index 0000000..e3dac5e
--- /dev/null
+++ b/core/java/android/security/FrameworkNetworkSecurityPolicy.java
@@ -0,0 +1,35 @@
+/**
+ * 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.security;
+
+/**
+ * Android framework's implementation of {@link libcore.net.NetworkSecurityPolicy}.
+ *
+ * @hide
+ */
+public class FrameworkNetworkSecurityPolicy extends libcore.net.NetworkSecurityPolicy {
+    private final boolean mCleartextTrafficPermitted;
+
+    public FrameworkNetworkSecurityPolicy(boolean cleartextTrafficPermitted) {
+        mCleartextTrafficPermitted = cleartextTrafficPermitted;
+    }
+
+    @Override
+    public boolean isCleartextTrafficPermitted() {
+        return mCleartextTrafficPermitted;
+    }
+}
diff --git a/core/java/android/security/NetworkSecurityPolicy.java b/core/java/android/security/NetworkSecurityPolicy.java
index 7e87717..7991d37 100644
--- a/core/java/android/security/NetworkSecurityPolicy.java
+++ b/core/java/android/security/NetworkSecurityPolicy.java
@@ -60,7 +60,7 @@
      * <p>NOTE: {@link android.webkit.WebView} does not honor this flag.
      */
     public boolean isCleartextTrafficPermitted() {
-        return libcore.net.NetworkSecurityPolicy.isCleartextTrafficPermitted();
+        return libcore.net.NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted();
     }
 
     /**
@@ -72,6 +72,7 @@
      * @hide
      */
     public void setCleartextTrafficPermitted(boolean permitted) {
-        libcore.net.NetworkSecurityPolicy.setCleartextTrafficPermitted(permitted);
+        FrameworkNetworkSecurityPolicy policy = new FrameworkNetworkSecurityPolicy(permitted);
+        libcore.net.NetworkSecurityPolicy.setInstance(policy);
     }
 }
diff --git a/core/java/android/security/net/config/ApplicationConfig.java b/core/java/android/security/net/config/ApplicationConfig.java
index b627641..71d9d5d 100644
--- a/core/java/android/security/net/config/ApplicationConfig.java
+++ b/core/java/android/security/net/config/ApplicationConfig.java
@@ -68,7 +68,7 @@
      */
     public NetworkSecurityConfig getConfigForHostname(String hostname) {
         ensureInitialized();
-        if (hostname.isEmpty() || mConfigs == null) {
+        if (hostname == null || hostname.isEmpty() || mConfigs == null) {
             return mDefaultConfig;
         }
         if (hostname.charAt(0) ==  '.') {
diff --git a/core/java/android/security/net/config/CertificateSource.java b/core/java/android/security/net/config/CertificateSource.java
index 2b7829e..7e3601e 100644
--- a/core/java/android/security/net/config/CertificateSource.java
+++ b/core/java/android/security/net/config/CertificateSource.java
@@ -23,4 +23,5 @@
 public interface CertificateSource {
     Set<X509Certificate> getCertificates();
     X509Certificate findBySubjectAndPublicKey(X509Certificate cert);
+    X509Certificate findByIssuerAndSignature(X509Certificate cert);
 }
diff --git a/core/java/android/security/net/config/CertificatesEntryRef.java b/core/java/android/security/net/config/CertificatesEntryRef.java
index 1d15e19..ff728ef 100644
--- a/core/java/android/security/net/config/CertificatesEntryRef.java
+++ b/core/java/android/security/net/config/CertificatesEntryRef.java
@@ -51,4 +51,13 @@
 
         return new TrustAnchor(foundCert, mOverridesPins);
     }
+
+    public TrustAnchor findByIssuerAndSignature(X509Certificate cert) {
+        X509Certificate foundCert = mSource.findByIssuerAndSignature(cert);
+        if (foundCert == null) {
+            return null;
+        }
+
+        return new TrustAnchor(foundCert, mOverridesPins);
+    }
 }
diff --git a/core/java/android/security/net/config/DirectoryCertificateSource.java b/core/java/android/security/net/config/DirectoryCertificateSource.java
index a261e06..bf29efa 100644
--- a/core/java/android/security/net/config/DirectoryCertificateSource.java
+++ b/core/java/android/security/net/config/DirectoryCertificateSource.java
@@ -95,6 +95,21 @@
         });
     }
 
+    @Override
+    public X509Certificate findByIssuerAndSignature(final X509Certificate cert) {
+        return findCert(cert.getIssuerX500Principal(), new CertSelector() {
+            @Override
+            public boolean match(X509Certificate ca) {
+                try {
+                    cert.verify(ca.getPublicKey());
+                    return true;
+                } catch (Exception e) {
+                    return false;
+                }
+            }
+        });
+    }
+
     private static interface CertSelector {
         boolean match(X509Certificate cert);
     }
diff --git a/core/java/android/security/net/config/KeyStoreCertificateSource.java b/core/java/android/security/net/config/KeyStoreCertificateSource.java
index 7a01a64..b6105cd 100644
--- a/core/java/android/security/net/config/KeyStoreCertificateSource.java
+++ b/core/java/android/security/net/config/KeyStoreCertificateSource.java
@@ -80,4 +80,14 @@
         }
         return anchor.getTrustedCert();
     }
+
+    @Override
+    public X509Certificate findByIssuerAndSignature(X509Certificate cert) {
+        ensureInitialized();
+        java.security.cert.TrustAnchor anchor = mIndex.findByIssuerAndSignature(cert);
+        if (anchor == null) {
+            return null;
+        }
+        return anchor.getTrustedCert();
+    }
 }
diff --git a/core/java/android/security/net/config/NetworkSecurityConfig.java b/core/java/android/security/net/config/NetworkSecurityConfig.java
index 2ab07b5..0a2edff 100644
--- a/core/java/android/security/net/config/NetworkSecurityConfig.java
+++ b/core/java/android/security/net/config/NetworkSecurityConfig.java
@@ -134,6 +134,17 @@
         return null;
     }
 
+    /** @hide */
+    public TrustAnchor findTrustAnchorByIssuerAndSignature(X509Certificate cert) {
+        for (CertificatesEntryRef ref : mCertificatesEntryRefs) {
+            TrustAnchor anchor = ref.findByIssuerAndSignature(cert);
+            if (anchor != null) {
+                return anchor;
+            }
+        }
+        return null;
+    }
+
     /**
      * Return a {@link Builder} for the default {@code NetworkSecurityConfig}.
      *
diff --git a/core/java/android/security/net/config/NetworkSecurityTrustManager.java b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
index 6013c1e..982ed68 100644
--- a/core/java/android/security/net/config/NetworkSecurityTrustManager.java
+++ b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
@@ -46,17 +46,13 @@
             throw new NullPointerException("config must not be null");
         }
         mNetworkSecurityConfig = config;
-        // TODO: Create our own better KeyStoreImpl
         try {
+            TrustedCertificateStoreAdapter certStore = new TrustedCertificateStoreAdapter(config);
+            // Provide an empty KeyStore since TrustManagerImpl doesn't support null KeyStores.
+            // TrustManagerImpl will use certStore to lookup certificates.
             KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
             store.load(null);
-            int certNum = 0;
-            for (TrustAnchor anchor : mNetworkSecurityConfig.getTrustAnchors()) {
-                store.setEntry(String.valueOf(certNum++),
-                        new KeyStore.TrustedCertificateEntry(anchor.certificate),
-                        null);
-            }
-            mDelegate = new TrustManagerImpl(store);
+            mDelegate = new TrustManagerImpl(store, null, certStore);
         } catch (GeneralSecurityException | IOException e) {
             throw new RuntimeException(e);
         }
diff --git a/core/java/android/security/net/config/ResourceCertificateSource.java b/core/java/android/security/net/config/ResourceCertificateSource.java
index b007f8f..e489c2c 100644
--- a/core/java/android/security/net/config/ResourceCertificateSource.java
+++ b/core/java/android/security/net/config/ResourceCertificateSource.java
@@ -90,4 +90,14 @@
         }
         return anchor.getTrustedCert();
     }
+
+    @Override
+    public X509Certificate findByIssuerAndSignature(X509Certificate cert) {
+        ensureInitialized();
+        java.security.cert.TrustAnchor anchor = mIndex.findByIssuerAndSignature(cert);
+        if (anchor == null) {
+            return null;
+        }
+        return anchor.getTrustedCert();
+    }
 }
diff --git a/core/java/android/security/net/config/TrustedCertificateStoreAdapter.java b/core/java/android/security/net/config/TrustedCertificateStoreAdapter.java
new file mode 100644
index 0000000..4a90f82
--- /dev/null
+++ b/core/java/android/security/net/config/TrustedCertificateStoreAdapter.java
@@ -0,0 +1,116 @@
+/*
+ * 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.security.net.config;
+
+import java.io.File;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Set;
+
+import com.android.org.conscrypt.TrustedCertificateStore;
+
+/** @hide */
+public class TrustedCertificateStoreAdapter extends TrustedCertificateStore {
+    private final NetworkSecurityConfig mConfig;
+
+    public TrustedCertificateStoreAdapter(NetworkSecurityConfig config) {
+        mConfig = config;
+    }
+
+    @Override
+    public X509Certificate findIssuer(X509Certificate cert) {
+        TrustAnchor anchor = mConfig.findTrustAnchorByIssuerAndSignature(cert);
+        if (anchor == null) {
+            return null;
+        }
+        return anchor.certificate;
+    }
+
+    @Override
+    public X509Certificate getTrustAnchor(X509Certificate cert) {
+        TrustAnchor anchor = mConfig.findTrustAnchorBySubjectAndPublicKey(cert);
+        if (anchor == null) {
+            return null;
+        }
+        return anchor.certificate;
+    }
+
+    @Override
+    public boolean isUserAddedCertificate(X509Certificate cert) {
+        // isUserAddedCertificate is used only for pinning overrides, so use overridesPins here.
+        TrustAnchor anchor = mConfig.findTrustAnchorBySubjectAndPublicKey(cert);
+        if (anchor == null) {
+            return false;
+        }
+        return anchor.overridesPins;
+    }
+
+    @Override
+    public File getCertificateFile(File dir, X509Certificate x) {
+        // getCertificateFile is only used for tests, do not support it here.
+        throw new UnsupportedOperationException();
+    }
+
+    // The methods below are exposed in TrustedCertificateStore but not used by conscrypt, do not
+    // support them.
+
+    @Override
+    public Certificate getCertificate(String alias) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Certificate getCertificate(String alias, boolean includeDeletedSystem) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Date getCreationDate(String alias) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Set<String> aliases() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Set<String> userAliases() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Set<String> allSystemAliases() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean containsAlias(String alias) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getCertificateAlias(Certificate c) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getCertificateAlias(Certificate c, boolean includeDeletedSystem) {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/core/java/android/speech/tts/FileSynthesisCallback.java b/core/java/android/speech/tts/FileSynthesisCallback.java
index c7a4ccc..dea766b 100644
--- a/core/java/android/speech/tts/FileSynthesisCallback.java
+++ b/core/java/android/speech/tts/FileSynthesisCallback.java
@@ -104,8 +104,8 @@
             Log.d(TAG, "FileSynthesisRequest.start(" + sampleRateInHz + "," + audioFormat
                     + "," + channelCount + ")");
         }
-        if (audioFormat != AudioFormat.ENCODING_PCM_8BIT ||
-            audioFormat != AudioFormat.ENCODING_PCM_16BIT ||
+        if (audioFormat != AudioFormat.ENCODING_PCM_8BIT &&
+            audioFormat != AudioFormat.ENCODING_PCM_16BIT &&
             audioFormat != AudioFormat.ENCODING_PCM_FLOAT) {
             Log.e(TAG, "Audio format encoding " + audioFormat + " not supported. Please use one " +
                        "of AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT or " +
diff --git a/core/java/android/speech/tts/PlaybackSynthesisCallback.java b/core/java/android/speech/tts/PlaybackSynthesisCallback.java
index a6fb543..dcc0095 100644
--- a/core/java/android/speech/tts/PlaybackSynthesisCallback.java
+++ b/core/java/android/speech/tts/PlaybackSynthesisCallback.java
@@ -123,8 +123,8 @@
     public int start(int sampleRateInHz, int audioFormat, int channelCount) {
         if (DBG) Log.d(TAG, "start(" + sampleRateInHz + "," + audioFormat + "," + channelCount
                 + ")");
-        if (audioFormat != AudioFormat.ENCODING_PCM_8BIT ||
-            audioFormat != AudioFormat.ENCODING_PCM_16BIT ||
+        if (audioFormat != AudioFormat.ENCODING_PCM_8BIT &&
+            audioFormat != AudioFormat.ENCODING_PCM_16BIT &&
             audioFormat != AudioFormat.ENCODING_PCM_FLOAT) {
             Log.w(TAG, "Audio format encoding " + audioFormat + " not supported. Please use one " +
                        "of AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT or " +
diff --git a/core/java/android/text/method/ArrowKeyMovementMethod.java b/core/java/android/text/method/ArrowKeyMovementMethod.java
index 2459cfa..57fe131 100644
--- a/core/java/android/text/method/ArrowKeyMovementMethod.java
+++ b/core/java/android/text/method/ArrowKeyMovementMethod.java
@@ -20,7 +20,6 @@
 import android.text.Layout;
 import android.text.Selection;
 import android.text.Spannable;
-import android.view.InputDevice;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
@@ -222,34 +221,26 @@
         return lineEnd(widget, buffer);
     }
 
-    private static boolean isTouchSelecting(boolean isMouse, Spannable buffer) {
-        return isMouse ? Touch.isActivelySelecting(buffer) : isSelecting(buffer);
-    }
-
     @Override
     public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
         int initialScrollX = -1;
         int initialScrollY = -1;
         final int action = event.getAction();
-        final boolean isMouse = event.isFromSource(InputDevice.SOURCE_MOUSE);
 
         if (action == MotionEvent.ACTION_UP) {
             initialScrollX = Touch.getInitialScrollX(widget, buffer);
             initialScrollY = Touch.getInitialScrollY(widget, buffer);
         }
 
-        boolean wasTouchSelecting = isTouchSelecting(isMouse, buffer);
+        boolean wasTouchSelecting = isSelecting(buffer);
         boolean handled = Touch.onTouchEvent(widget, buffer, event);
 
-        if (widget.didTouchFocusSelect() && !isMouse) {
+        if (widget.didTouchFocusSelect()) {
             return handled;
         }
         if (action == MotionEvent.ACTION_DOWN) {
-            // Capture the mouse pointer down location to ensure selection starts
-            // right under the mouse (and is not influenced by cursor location).
-            // The code below needs to run for mouse events.
             // For touch events, the code should run only when selection is active.
-            if (isMouse || isTouchSelecting(isMouse, buffer)) {
+            if (isSelecting(buffer)) {
                 if (!widget.isFocused()) {
                     if (!widget.requestFocus()) {
                         return handled;
@@ -265,15 +256,8 @@
             }
         } else if (widget.isFocused()) {
             if (action == MotionEvent.ACTION_MOVE) {
-                // Cursor can be active at any location in the text while mouse pointer can start
-                // selection from a totally different location. Use LAST_TAP_DOWN span to ensure
-                // text selection will start from mouse pointer location.
-                final int startOffset = buffer.getSpanStart(LAST_TAP_DOWN);
-                if (isMouse && Touch.isSelectionStarted(buffer)) {
-                    Selection.setSelection(buffer, startOffset);
-                }
-
-                if (isTouchSelecting(isMouse, buffer) && handled) {
+                if (isSelecting(buffer) && handled) {
+                    final int startOffset = buffer.getSpanStart(LAST_TAP_DOWN);
                     // Before selecting, make sure we've moved out of the "slop".
                     // handled will be true, if we're in select mode AND we're
                     // OUT of the slop
diff --git a/core/java/android/text/method/Touch.java b/core/java/android/text/method/Touch.java
index fee7377..d9068dc 100644
--- a/core/java/android/text/method/Touch.java
+++ b/core/java/android/text/method/Touch.java
@@ -119,18 +119,12 @@
             ds = buffer.getSpans(0, buffer.length(), DragState.class);
 
             if (ds.length > 0) {
-                ds[0].mIsSelectionStarted = false;
-
                 if (ds[0].mFarEnough == false) {
                     int slop = ViewConfiguration.get(widget.getContext()).getScaledTouchSlop();
 
                     if (Math.abs(event.getX() - ds[0].mX) >= slop ||
                         Math.abs(event.getY() - ds[0].mY) >= slop) {
                         ds[0].mFarEnough = true;
-                        if (event.isButtonPressed(MotionEvent.BUTTON_PRIMARY)) {
-                            ds[0].mIsActivelySelecting = true;
-                            ds[0].mIsSelectionStarted = true;
-                        }
                     }
                 }
 
@@ -142,13 +136,9 @@
                             || MetaKeyKeyListener.getMetaState(buffer,
                                     MetaKeyKeyListener.META_SELECTING) != 0;
 
-                    if (!event.isButtonPressed(MotionEvent.BUTTON_PRIMARY)) {
-                        ds[0].mIsActivelySelecting = false;
-                    }
-
                     float dx;
                     float dy;
-                    if (cap && event.isButtonPressed(MotionEvent.BUTTON_PRIMARY)) {
+                    if (cap) {
                         // if we're selecting, we want the scroll to go in
                         // the direction of the drag
                         dx = event.getX() - ds[0].mX;
@@ -160,7 +150,6 @@
                     ds[0].mX = event.getX();
                     ds[0].mY = event.getY();
 
-                    int nx = widget.getScrollX() + (int) dx;
                     int ny = widget.getScrollY() + (int) dy;
 
                     int padding = widget.getTotalPaddingTop() + widget.getTotalPaddingBottom();
@@ -172,10 +161,6 @@
                     int oldX = widget.getScrollX();
                     int oldY = widget.getScrollY();
 
-                    if (!event.isButtonPressed(MotionEvent.BUTTON_PRIMARY)) {
-                        scrollTo(widget, layout, nx, ny);
-                    }
-
                     // If we actually scrolled, then cancel the up action.
                     if (oldX != widget.getScrollX() || oldY != widget.getScrollY()) {
                         widget.cancelLongPress();
@@ -207,37 +192,6 @@
         return ds.length > 0 ? ds[0].mScrollY : -1;
     }
 
-    /**
-     * Checks if selection is still active.
-     * This is useful for extending Selection span on buffer.
-     * @param buffer The text buffer.
-     * @return true if buffer has been marked for selection.
-     *
-     * @hide
-     */
-    static boolean isActivelySelecting(Spannable buffer) {
-        DragState[] ds;
-        ds = buffer.getSpans(0, buffer.length(), DragState.class);
-
-        return ds.length > 0 && ds[0].mIsActivelySelecting;
-    }
-
-    /**
-     * Checks if selection has begun (are we out of slop?).
-     * Note: DragState.mIsSelectionStarted goes back to false with the very next event.
-     * This is useful for starting Selection span on buffer.
-     * @param buffer The text buffer.
-     * @return true if selection has started on the buffer.
-     *
-     * @hide
-     */
-    static boolean isSelectionStarted(Spannable buffer) {
-        DragState[] ds;
-        ds = buffer.getSpans(0, buffer.length(), DragState.class);
-
-        return ds.length > 0 && ds[0].mIsSelectionStarted;
-    }
-
     private static class DragState implements NoCopySpan {
         public float mX;
         public float mY;
@@ -245,8 +199,6 @@
         public int mScrollY;
         public boolean mFarEnough;
         public boolean mUsed;
-        public boolean mIsActivelySelecting;
-        public boolean mIsSelectionStarted;
 
         public DragState(float x, float y, int scrollX, int scrollY) {
             mX = x;
diff --git a/core/java/android/text/method/WordIterator.java b/core/java/android/text/method/WordIterator.java
index 3688cfa..664d1ea 100644
--- a/core/java/android/text/method/WordIterator.java
+++ b/core/java/android/text/method/WordIterator.java
@@ -20,7 +20,7 @@
 import android.text.Selection;
 import android.text.SpannableStringBuilder;
 
-import java.text.BreakIterator;
+import android.icu.text.BreakIterator;
 import java.util.Locale;
 
 /**
diff --git a/core/java/android/util/ArrayMap.java b/core/java/android/util/ArrayMap.java
index 4ee9807..bdb1fdc 100644
--- a/core/java/android/util/ArrayMap.java
+++ b/core/java/android/util/ArrayMap.java
@@ -60,6 +60,11 @@
     private static final int CACHE_SIZE = 10;
 
     /**
+     * Special hash array value that indicates the container is immutable.
+     */
+    static final int[] EMPTY_IMMUTABLE_INTS = new int[0];
+
+    /**
      * @hide Special immutable empty ArrayMap.
      */
     public static final ArrayMap EMPTY = new ArrayMap(true);
@@ -75,11 +80,6 @@
     static Object[] mTwiceBaseCache;
     static int mTwiceBaseCacheSize;
 
-    /**
-     * Special hash array value that indicates the container is immutable.
-     */
-    static final int[] EMPTY_IMMUTABLE_INTS = new int[0];
-
     int[] mHashes;
     Object[] mArray;
     int mSize;
diff --git a/core/java/android/util/LocaleList.java b/core/java/android/util/LocaleList.java
index b2ee045..1becfb4 100644
--- a/core/java/android/util/LocaleList.java
+++ b/core/java/android/util/LocaleList.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.Size;
+import android.icu.util.ULocale;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -208,10 +209,66 @@
         }
     }
 
+    private static String getLikelyScript(Locale locale) {
+        final String script = locale.getScript();
+        if (!script.isEmpty()) {
+            return script;
+        } else {
+            // TODO: Cache the results if this proves to be too slow
+            return ULocale.addLikelySubtags(ULocale.forLocale(locale)).getScript();
+        }
+    }
+
+    private static int matchScore(Locale supported, Locale desired) {
+        if (supported.equals(desired)) {
+            return 1;  // return early so we don't do unnecessary computation
+        }
+        if (!supported.getLanguage().equals(desired.getLanguage())) {
+            return 0;
+        }
+        // There is no match if the two locales use different scripts. This will most imporantly
+        // take care of traditional vs simplified Chinese.
+        final String supportedScr = getLikelyScript(supported);
+        final String desiredScr = getLikelyScript(desired);
+        return supportedScr.equals(desiredScr) ? 1 : 0;
+    }
+
+    /**
+     * Returns the first match in the locale list given an unordered array of supported locales
+     * in BCP47 format.
+     *
+     * If the locale list is empty, null would be returned.
+     */
     @Nullable
-    public Locale getBestMatch(String[] locales) {
-        // TODO: Fix this to actually do locale negotiation and choose the best match
-        return getPrimary();
+    public Locale getFirstMatch(String[] supportedLocales) {
+        if (mList.length == 1) {  // just one locale, perhaps the most common scenario
+            return mList[0];
+        }
+        if (mList.length == 0) {  // empty locale list
+            return null;
+        }
+        // TODO: Figure out what to if en-XA or ar-XB are in the locale list
+        int bestIndex = Integer.MAX_VALUE;
+        for (String tag : supportedLocales) {
+            final Locale supportedLocale = Locale.forLanguageTag(tag);
+            // We expect the average length of locale lists used for locale resolution to be
+            // smaller than three, so it's OK to do this as an O(mn) algorithm.
+            for (int idx = 0; idx < mList.length; idx++) {
+                final int score = matchScore(supportedLocale, mList[idx]);
+                if (score > 0) {
+                    if (idx == 0) {  // We have a match on the first locale, which is good enough
+                        return mList[0];
+                    } else if (idx < bestIndex) {
+                        bestIndex = idx;
+                    }
+                }
+            }
+        }
+        if (bestIndex == Integer.MAX_VALUE) {  // no match was found
+            return mList[0];
+        } else {
+            return mList[bestIndex];
+        }
     }
 
     private final static Object sLock = new Object();
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index bae51d3..46b9a46 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -256,6 +256,15 @@
     public static final int SOURCE_TOUCH_NAVIGATION = 0x00200000 | SOURCE_CLASS_NONE;
 
     /**
+     * The input source is a rotating encoder device whose motions should be interpreted as akin to
+     * those of a scroll wheel.
+     *
+     * @see #SOURCE_CLASS_NONE
+     * {@hide}
+     */
+    public static final int SOURCE_ROTARY_ENCODER = 0x00400000 | SOURCE_CLASS_NONE;
+
+    /**
      * The input source is a joystick.
      * (It may also be a {@link #SOURCE_GAMEPAD}).
      *
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 6026d04..0195dec 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -962,6 +962,21 @@
     public static final int AXIS_TILT = 25;
 
     /**
+     * Axis constant: Generic scroll axis of a motion event.
+     * <p>
+     * <ul>
+     * <li>Reports the relative movement of the generic scrolling device.
+     * </ul>
+     * </p><p>
+     * This axis should be used for scroll events that are neither strictly vertical nor horizontal.
+     * A good example would be the rotation of a rotary encoder input device.
+     * </p>
+     *
+     * @see #getAxisValue(int, int)
+     */
+    public static final int AXIS_SCROLL = 26;
+
+    /**
      * Axis constant: Generic 1 axis of a motion event.
      * The interpretation of a generic axis is device-specific.
      *
@@ -1171,6 +1186,7 @@
         names.append(AXIS_BRAKE, "AXIS_BRAKE");
         names.append(AXIS_DISTANCE, "AXIS_DISTANCE");
         names.append(AXIS_TILT, "AXIS_TILT");
+        names.append(AXIS_SCROLL, "AXIS_SCROLL");
         names.append(AXIS_GENERIC_1, "AXIS_GENERIC_1");
         names.append(AXIS_GENERIC_2, "AXIS_GENERIC_2");
         names.append(AXIS_GENERIC_3, "AXIS_GENERIC_3");
diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java
index 82f6c7f..54fa764 100644
--- a/core/java/android/view/NotificationHeaderView.java
+++ b/core/java/android/view/NotificationHeaderView.java
@@ -17,10 +17,10 @@
 package android.view;
 
 import android.annotation.Nullable;
-import android.app.Notification;
 import android.content.Context;
 import android.graphics.Rect;
 import android.util.AttributeSet;
+import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.RemoteViews;
 import android.widget.TextView;
@@ -34,14 +34,20 @@
  */
 @RemoteViews.RemoteView
 public class NotificationHeaderView extends LinearLayout {
+    public static final int NO_COLOR = -1;
     private final int mHeaderMinWidth;
+    private final int mExpandTopPadding;
     private View mAppName;
     private View mSubTextView;
     private OnClickListener mExpandClickListener;
     private HeaderTouchListener mTouchListener = new HeaderTouchListener();
-    private View mExpandButton;
+    private ImageView mExpandButton;
     private View mIcon;
     private TextView mChildCount;
+    private int mIconColor;
+    private int mOriginalNotificationColor;
+    private boolean mGroupHeader;
+    private boolean mExpanded;
 
     public NotificationHeaderView(Context context) {
         this(context, null);
@@ -59,6 +65,7 @@
         super(context, attrs, defStyleAttr, defStyleRes);
         mHeaderMinWidth = getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.notification_header_shrink_min_width);
+        mExpandTopPadding = (int) (1 * getResources().getDisplayMetrics().density);
     }
 
     @Override
@@ -66,7 +73,7 @@
         super.onFinishInflate();
         mAppName = findViewById(com.android.internal.R.id.app_name_text);
         mSubTextView = findViewById(com.android.internal.R.id.header_sub_text);
-        mExpandButton = findViewById(com.android.internal.R.id.expand_button);
+        mExpandButton = (ImageView) findViewById(com.android.internal.R.id.expand_button);
         mIcon = findViewById(com.android.internal.R.id.icon);
         mChildCount = (TextView) findViewById(com.android.internal.R.id.number_of_children);
     }
@@ -98,7 +105,7 @@
             int overFlow = totalWidth - givenWidth;
             // We are overflowing, lets shrink
             final int appWidth = mAppName.getMeasuredWidth();
-            if (appWidth > mHeaderMinWidth) {
+            if (mAppName.getVisibility() != GONE && appWidth > mHeaderMinWidth) {
                 int newSize = appWidth - Math.min(appWidth - mHeaderMinWidth, overFlow);
                 int childWidthSpec = MeasureSpec.makeMeasureSpec(newSize, MeasureSpec.AT_MOST);
                 mAppName.measure(childWidthSpec, wrapContentHeightSpec);
@@ -146,6 +153,57 @@
         }
     }
 
+    @RemotableViewMethod
+    public void setOriginalIconColor(int color) {
+        mIconColor = color;
+    }
+
+    public int getOriginalIconColor() {
+        return mIconColor;
+    }
+
+    @RemotableViewMethod
+    public void setOriginalNotificationColor(int color) {
+        mOriginalNotificationColor = color;
+    }
+
+    public int getOriginalNotificationColor() {
+        return mOriginalNotificationColor;
+    }
+
+    public void setIsGroupHeader(boolean isGroupHeader) {
+        mGroupHeader = isGroupHeader;
+        updateExpandButton();
+    }
+
+    @RemotableViewMethod
+    public void setExpanded(boolean expanded) {
+        mExpanded = expanded;
+        updateExpandButton();
+    }
+
+    private void updateExpandButton() {
+        int drawableId;
+        int paddingTop = 0;
+        if (mGroupHeader) {
+            if (mExpanded) {
+                drawableId = com.android.internal.R.drawable.ic_collapse_bundle;
+            } else {
+                drawableId =com.android.internal.R.drawable.ic_expand_bundle;
+            }
+        } else {
+            if (mExpanded) {
+                drawableId = com.android.internal.R.drawable.ic_collapse_notification;
+            } else {
+                drawableId = com.android.internal.R.drawable.ic_expand_notification;
+            }
+            paddingTop = mExpandTopPadding;
+        }
+        mExpandButton.setImageDrawable(getContext().getDrawable(drawableId));
+        mExpandButton.setColorFilter(mOriginalNotificationColor);
+        mExpandButton.setPadding(0, paddingTop, 0, 0);
+    }
+
     public class HeaderTouchListener implements View.OnTouchListener {
 
         private final ArrayList<Rect> mTouchRects = new ArrayList<>();
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 6dd87a0..183ccf3 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -83,7 +83,6 @@
 import android.view.AccessibilityIterators.CharacterTextSegmentIterator;
 import android.view.AccessibilityIterators.WordTextSegmentIterator;
 import android.view.AccessibilityIterators.ParagraphTextSegmentIterator;
-import android.view.ViewGroup.LayoutParams;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityEventSource;
 import android.view.accessibility.AccessibilityManager;
@@ -2423,8 +2422,6 @@
      *                    1              PFLAG3_SCROLL_INDICATOR_END
      *                   1               PFLAG3_ASSIST_BLOCKED
      *            1111111                PFLAG3_POINTER_ICON_MASK
-     *           1                       PFLAG3_PARTIAL_LAYOUT_REQUESTED
-     *          1                        PFLAG3_LAYOUT_PARAMS_CHANGED
      * |-------|-------|-------|-------|
      */
 
@@ -2513,7 +2510,6 @@
      */
     static final int PFLAG3_SCROLL_INDICATOR_END = 0x2000;
 
-
     /* End of masks for mPrivateFlags3 */
 
     static final int DRAG_MASK = PFLAG2_DRAG_CAN_ACCEPT | PFLAG2_DRAG_HOVERED;
@@ -2652,19 +2648,6 @@
     private static final int PFLAG3_POINTER_ICON_VALUE_START = 3 << PFLAG3_POINTER_ICON_LSHIFT;
 
     /**
-     * Flag indicating that this view has requested a partial layout and
-     * is added to the AttachInfo's list of views that need a partial layout
-     * request handled on the next traversal.
-     */
-    static final int PFLAG3_PARTIAL_LAYOUT_REQUESTED = 0x800000;
-
-    /**
-     * Flag indicating that this view's LayoutParams have been explicitly changed
-     * since the last layout pass.
-     */
-    static final int PFLAG3_LAYOUT_PARAMS_CHANGED = 0x1000000;
-
-    /**
      * Always allow a user to over-scroll this view, provided it is a
      * view that can scroll.
      *
@@ -12671,14 +12654,10 @@
      * ViewGroup.LayoutParams, and these correspond to the different subclasses
      * of ViewGroup that are responsible for arranging their children.
      *
-     * <p>This method may return null if this View is not attached to a parent
+     * This method may return null if this View is not attached to a parent
      * ViewGroup or {@link #setLayoutParams(android.view.ViewGroup.LayoutParams)}
      * was not invoked successfully. When a View is attached to a parent
-     * ViewGroup, this method must not return null.</p>
-     *
-     * <p>Callers that modify the returned LayoutParams object should call
-     * {@link #setLayoutParams(LayoutParams)} to explicitly inform the view that
-     * LayoutParams have changed.</p>
+     * ViewGroup, this method must not return null.
      *
      * @return The LayoutParams associated with this view, or null if no
      *         parameters have been set yet
@@ -12695,9 +12674,6 @@
      * correspond to the different subclasses of ViewGroup that are responsible
      * for arranging their children.
      *
-     * <p>If the View's existing LayoutParams object as obtained by {@link #getLayoutParams()} is
-     * modified, you should call this method to inform the view that it has changed.</p>
-     *
      * @param params The layout parameters for this view, cannot be null
      */
     public void setLayoutParams(ViewGroup.LayoutParams params) {
@@ -12705,7 +12681,6 @@
             throw new NullPointerException("Layout parameters cannot be null");
         }
         mLayoutParams = params;
-        mPrivateFlags3 |= PFLAG3_LAYOUT_PARAMS_CHANGED;
         resolveLayoutParams();
         if (mParent instanceof ViewGroup) {
             ((ViewGroup) mParent).onSetLayoutParams(this, params);
@@ -14381,12 +14356,7 @@
             mParent.requestTransparentRegion(this);
         }
 
-        if ((mPrivateFlags & PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH) != 0) {
-            initialAwakenScrollBars();
-            mPrivateFlags &= ~PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH;
-        }
-
-        mPrivateFlags3 &= ~(PFLAG3_IS_LAID_OUT | PFLAG3_PARTIAL_LAYOUT_REQUESTED);
+        mPrivateFlags3 &= ~PFLAG3_IS_LAID_OUT;
 
         jumpDrawablesToCurrentState();
 
@@ -14724,13 +14694,8 @@
      */
     @CallSuper
     protected void onDetachedFromWindowInternal() {
-        if (mAttachInfo != null && isPartialLayoutRequested()) {
-            mAttachInfo.mPartialLayoutViews.remove(this);
-        }
-
         mPrivateFlags &= ~PFLAG_CANCEL_NEXT_UP_EVENT;
-        mPrivateFlags3 &= ~(PFLAG3_IS_LAID_OUT | PFLAG3_PARTIAL_LAYOUT_REQUESTED
-                | PFLAG3_LAYOUT_PARAMS_CHANGED);
+        mPrivateFlags3 &= ~PFLAG3_IS_LAID_OUT;
 
         removeUnsetPressCallback();
         removeLongPressCallback();
@@ -16917,32 +16882,6 @@
     }
 
     /**
-     * Indicates whether or not this view has requested a partial layout that
-     * may not affect its size or position within its parent. This state will be reset
-     * the next time this view is laid out.
-     *
-     * @return true if partial layout has been requested
-     */
-    public final boolean isPartialLayoutRequested() {
-        return (mPrivateFlags3 & PFLAG3_PARTIAL_LAYOUT_REQUESTED)
-                == PFLAG3_PARTIAL_LAYOUT_REQUESTED;
-    }
-
-    /**
-     * Returns true if this view's {@link ViewGroup.LayoutParams LayoutParams} changed
-     * since the last time this view was successfully laid out. Typically this happens as a
-     * result of a call to {@link #setLayoutParams(LayoutParams)}.
-     *
-     * @return true if this view's LayoutParams changed since last layout.
-     */
-    public final boolean didLayoutParamsChange() {
-        if (sLayoutParamsAlwaysChanged) {
-            return true;
-        }
-        return (mPrivateFlags3 & PFLAG3_LAYOUT_PARAMS_CHANGED) == PFLAG3_LAYOUT_PARAMS_CHANGED;
-    }
-
-    /**
      * Return true if o is a ViewGroup that is laying out using optical bounds.
      * @hide
      */
@@ -16999,7 +16938,6 @@
         if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) {
             onLayout(changed, l, t, r, b);
             mPrivateFlags &= ~PFLAG_LAYOUT_REQUIRED;
-            mPrivateFlags3 &= ~PFLAG3_LAYOUT_PARAMS_CHANGED;
 
             ListenerInfo li = mListenerInfo;
             if (li != null && li.mOnLayoutChangeListeners != null) {
@@ -17013,7 +16951,6 @@
         }
 
         mPrivateFlags &= ~PFLAG_FORCE_LAYOUT;
-        mPrivateFlags3 &= ~PFLAG3_PARTIAL_LAYOUT_REQUESTED;
         mPrivateFlags3 |= PFLAG3_IS_LAID_OUT;
     }
 
@@ -19111,7 +19048,7 @@
         mPrivateFlags |= PFLAG_INVALIDATED;
 
         if (mParent != null && !mParent.isLayoutRequested()) {
-            mParent.requestLayoutForChild(this);
+            mParent.requestLayout();
         }
         if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == this) {
             mAttachInfo.mViewRequestingLayout = null;
@@ -19130,11 +19067,6 @@
         mPrivateFlags |= PFLAG_INVALIDATED;
     }
 
-    void forcePartialLayout() {
-        forceLayout();
-        mPrivateFlags3 |= PFLAG3_PARTIAL_LAYOUT_REQUESTED;
-    }
-
     /**
      * <p>
      * This is called to find out how big a view should be. The parent
@@ -22021,7 +21953,6 @@
         interface Callbacks {
             void playSoundEffect(int effectId);
             boolean performHapticFeedback(int effectId, boolean always);
-            void schedulePartialLayout();
         }
 
         /**
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 11df9a3..0f7d296 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -60,8 +60,6 @@
 import java.util.List;
 import java.util.Map;
 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 
 /**
  * <p>
@@ -5531,172 +5529,6 @@
             int l, int t, int r, int b);
 
     /**
-     * {@inheritDoc}
-     *
-     * <p>Most subclasses should not need to override this method. The default implementation
-     * will call {@link #findDependentLayoutAxes(View, int)} to determine how
-     * to optimally proceed. If neither horizontal nor vertical layout depends on the given
-     * child, this method will call {@link #requestPartialLayoutForChild(View)}. If one or both
-     * do, it will call {@link #requestLayout()}.</p>
-     *
-     * @param child Child requesting a layout
-     */
-    @Override
-    public void requestLayoutForChild(View child) {
-        if (child == null || child.getParent() != this) {
-            throw new IllegalArgumentException(
-                    "child parameter must be a direct child view of this ViewGroup");
-        }
-
-        // If we don't have a parent ourselves, record that we need a full layout.
-        // Our whole subtree is detached.
-        final ViewParent parent = getParent();
-        if (parent == null) {
-            requestLayout();
-            return;
-        }
-
-        // We can optimize the layout request for this child into a partial layout
-        // if the child has already been laid out at least once and neither horizontal nor
-        // vertical layout within ourselves is dependent on pending layout changes within
-        // this child. Otherwise we need to request a full layout for ourselves and continue
-        // to recurse up the view hierarchy.
-        if (child.isLaidOut() && findDependentLayoutAxes(child, FLAG_LAYOUT_AXIS_ANY) == 0) {
-            requestPartialLayoutForChild(child);
-        } else {
-            requestLayout();
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * <p>The default implementation returns {@link #FLAG_LAYOUT_AXIS_ANY}.
-     * Optimized implementations for specific ViewGroup subclasses may check if the child's
-     * {@link View#didLayoutParamsChange() LayoutParams changed} and in what ways.</p>
-     *
-     * @param child Direct child of this ViewParent to check
-     * @param axisFilter Which axes to check for dependencies. Can be
-     *                   {@link #FLAG_LAYOUT_AXIS_HORIZONTAL}, {@link #FLAG_LAYOUT_AXIS_VERTICAL}
-     *                   or {@link #FLAG_LAYOUT_AXIS_ANY}.
-     * @return Axes of this ViewParent that depend on the given child's layout changes
-     */
-    @Override
-    public int findDependentLayoutAxes(View child, int axisFilter) {
-        return FLAG_LAYOUT_AXIS_ANY;
-    }
-
-    /**
-     * This is a helper implementation for {@link #findDependentLayoutAxes(View, int)} that
-     * is not the default implementation in ViewGroup. This is to preserve compatibility with
-     * existing app-side ViewGroup subclasses that existed before the partial layout system was
-     * added to Android. It explicitly checks that the LayoutParams of the child are of the
-     * expected type so that subclasses of standard framework layouts do not erroneously
-     * start believing that it's safe to do a partial layout when that assertion can't
-     * reasonably be confirmed.
-     *
-     * <p>If you're reading this as an author of a custom ViewGroup's findDependentLayoutAxes
-     * method you might be frustrated to discover that it is not a part of the Android public API.
-     * Many ViewGroup implementations will need to make small but important modifications
-     * to an implementation like this one in order to be correct. Instead of encouraging
-     * view authors to call this method, then make their own redundant recursive calls to
-     * <code>getParent().findDependentLayoutAxes(...)</code> in addition to the one
-     * that can happen here, this method is hidden and only used internally.</p>
-     *
-     * <p>Do feel free to copy this implementation and adapt it to suit your own purposes.</p>
-     *
-     * @hide
-     */
-    protected final int findDependentLayoutAxesHelper(View child, int axisFilter,
-            Class<?> layoutParamsClass) {
-        if (!checkPartialLayoutParams(child, layoutParamsClass)) return axisFilter;
-        if (child.didLayoutParamsChange()) {
-            // Anything could have changed about our previous assumptions.
-            return axisFilter;
-        }
-
-        final LayoutParams lp = child.getLayoutParams();
-
-        // Our layout can always end up depending on a WRAP_CONTENT child.
-        final int wrapAxisFilter = ((lp.width == WRAP_CONTENT ? FLAG_LAYOUT_AXIS_HORIZONTAL : 0)
-                | (lp.height == WRAP_CONTENT ? FLAG_LAYOUT_AXIS_VERTICAL : 0)) & axisFilter;
-
-        if (wrapAxisFilter == axisFilter) {
-            // We know all queried axes are affected, just return early.
-            return wrapAxisFilter;
-        }
-
-        // Our layout *may* depend on a MATCH_PARENT child, depending on whether we can determine
-        // that our layout will remain stable within our parent. We need to ask.
-        final int matchAxisFilter = ((lp.width == MATCH_PARENT ? FLAG_LAYOUT_AXIS_HORIZONTAL : 0)
-                | (lp.height == MATCH_PARENT ? FLAG_LAYOUT_AXIS_VERTICAL : 0)) & axisFilter;
-
-        if (matchAxisFilter != 0) {
-            final ViewParent parent = getParent();
-            if (parent != null) {
-                // If our parent depends on us for an axis, then our layout can also be affected
-                // by a MATCH_PARENT child along that axis.
-                return getParent().findDependentLayoutAxes(this, matchAxisFilter)
-                        | wrapAxisFilter;
-            }
-
-            // If we don't have a parent, assume we're affected
-            // in any determined affected direction.
-            return matchAxisFilter | wrapAxisFilter;
-        }
-
-        // Two exact sizes and LayoutParams didn't change. We're safe.
-        return 0;
-    }
-
-    /**
-     * Throw an IllegalArgumentException if the supplied view is not a direct child of
-     * this ViewGroup and return false if this view's LayoutParams is not of class lpClass.
-     * Implementations of {@link ViewGroup#findDependentLayoutAxes(View, int)} use this
-     * to check input parameters and defensively return the full axis filter mask themselves
-     * if the LayoutParams class is not of the exact expected type; e.g. it is a subclass
-     * of one of the standard framework layouts and we can't make assumptions.
-     * @hide
-     */
-    protected final boolean checkPartialLayoutParams(View child, Class<?> lpClass) {
-        if (child.getParent() != this) {
-            throw new IllegalArgumentException("View " + child
-                    + " is not a direct child of " + this);
-        }
-        final ViewGroup.LayoutParams lp = child.getLayoutParams();
-        return lp != null || lp.getClass() == lpClass;
-    }
-
-    /**
-     * Called when a child of this ViewParent requires a relayout before the next frame
-     * is drawn, but the caller can guarantee that the size of the child will not change
-     * during a measure and layout pass.
-     *
-     * <p>A call to this method will schedule a partial layout for the supplied view as long as
-     * it is a direct child of this ViewGroup and this ViewGroup is attached to a window.
-     * On the next scheduled view hierarchy traversal the given child view will be re-measured
-     * at its current measured size and re-laid out at its current position within its parent.</p>
-     *
-     * @param child Child that requires a partial layout
-     */
-    public void requestPartialLayoutForChild(View child) {
-        if (!child.isPartialLayoutRequested()) {
-            child.forcePartialLayout();
-            if (mAttachInfo != null) {
-                final List<View> partialLayoutViews = mAttachInfo.mPartialLayoutViews;
-                final boolean schedule = partialLayoutViews.isEmpty();
-                partialLayoutViews.add(child);
-                if (schedule) {
-                    mAttachInfo.mRootCallbacks.schedulePartialLayout();
-                }
-                child.invalidate();
-            } else {
-                requestLayout();
-            }
-        }
-    }
-
-    /**
      * Indicates whether the view group has the ability to animate its children
      * after the first layout.
      *
@@ -6042,7 +5874,7 @@
      *         of its descendants
      */
     protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
-        return new LayoutParams(p);
+        return p;
     }
 
     /**
diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java
index f2ab35e..e9b123b5 100644
--- a/core/java/android/view/ViewParent.java
+++ b/core/java/android/view/ViewParent.java
@@ -26,11 +26,6 @@
  * 
  */
 public interface ViewParent {
-    public static final int FLAG_LAYOUT_AXIS_HORIZONTAL = 1;
-    public static final int FLAG_LAYOUT_AXIS_VERTICAL = 2;
-    public static final int FLAG_LAYOUT_AXIS_ANY
-            = FLAG_LAYOUT_AXIS_HORIZONTAL | FLAG_LAYOUT_AXIS_VERTICAL;
-
     /**
      * Called when something has changed which has invalidated the layout of a
      * child of this view parent. This will schedule a layout pass of the view
@@ -618,48 +613,4 @@
      * @return true if the action was consumed by this ViewParent
      */
     public boolean onNestedPrePerformAccessibilityAction(View target, int action, Bundle arguments);
-
-    /**
-     * Called when a child of this ViewParent requires a relayout before
-     * the next frame is drawn. A call to {@link View#requestLayout() child.requestLayout()}
-     * will implicitly result in a call to
-     * <code>child.getParent().requestLayoutForChild(child)</code>. App code should not call this
-     * method directly. Call <code>child.requestLayout()</code> instead.
-     *
-     * <p>On versions of Android from API 23 and older, a call to {@link View#requestLayout()}
-     * would cause a matching call to <code>requestLayout</code> on each parent view up to
-     * the root. With the addition of <code>requestLayoutForChild</code> a view's parent may
-     * explicitly decide how to handle a layout request. This allows for optimizations when
-     * a view parent knows that a layout-altering change in a child will not affect its own
-     * measurement.</p>
-     *
-     * @param child Child requesting a layout
-     */
-    public void requestLayoutForChild(View child);
-
-    /**
-     * Determine which axes of this ViewParent's layout are dependent on the given
-     * direct child view. The returned value is a flag set that may contain
-     * {@link #FLAG_LAYOUT_AXIS_HORIZONTAL} and/or {@link #FLAG_LAYOUT_AXIS_VERTICAL}.
-     * {@link #FLAG_LAYOUT_AXIS_ANY} is provided as a shortcut for
-     * <code>FLAG_LAYOUT_AXIS_HORIZONTAL | FLAG_LAYOUT_AXIS_VERTICAL</code>.
-     *
-     * <p>The given child must be a direct child view. Implementations should throw
-     * {@link IllegalArgumentException} otherwise.</p>
-     *
-     * <p>The caller may specify which axes it cares about. This should be treated as a filter.
-     * Implementations should never return a result that would be different from
-     * <code>result & axisFilter</code>.</p>
-     *
-     * @param child Direct child of this ViewParent to check
-     * @param axisFilter Which axes to check for dependencies. Can be
-     *                   {@link #FLAG_LAYOUT_AXIS_HORIZONTAL}, {@link #FLAG_LAYOUT_AXIS_VERTICAL}
-     *                   or {@link #FLAG_LAYOUT_AXIS_ANY}.
-     * @return Axes of this ViewParent that depend on the given child's layout changes
-     *
-     * @see #FLAG_LAYOUT_AXIS_HORIZONTAL
-     * @see #FLAG_LAYOUT_AXIS_VERTICAL
-     * @see #FLAG_LAYOUT_AXIS_ANY
-     */
-    public int findDependentLayoutAxes(View child, int axisFilter);
 }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index b7bb9a3..12cf66e 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -91,7 +91,6 @@
 import java.util.ArrayList;
 import java.util.concurrent.CountDownLatch;
 import java.util.HashSet;
-import java.util.List;
 
 /**
  * The top of a view hierarchy, implementing the needed protocol between View
@@ -953,25 +952,6 @@
     }
 
     @Override
-    public void requestLayoutForChild(View child) {
-        requestLayout();
-    }
-
-    @Override
-    public int findDependentLayoutAxes(View child, int axisFilter) {
-        if (child != mView) {
-            return 0;
-        }
-
-        final WindowManager.LayoutParams lp = (WindowManager.LayoutParams) child.getLayoutParams();
-        final int horizontal = (lp.width == WindowManager.LayoutParams.WRAP_CONTENT
-                || lp.horizontalWeight != 0) ? FLAG_LAYOUT_AXIS_HORIZONTAL : 0;
-        final int vertical = (lp.height == WindowManager.LayoutParams.WRAP_CONTENT
-                || lp.verticalWeight != 0) ? FLAG_LAYOUT_AXIS_VERTICAL : 0;
-        return (horizontal | vertical) & axisFilter;
-    }
-
-    @Override
     public boolean isLayoutRequested() {
         return mLayoutRequested;
     }
@@ -1115,10 +1095,6 @@
         }
     }
 
-    public void schedulePartialLayout() {
-        scheduleTraversals();
-    }
-
     /**
      * Notifies the HardwareRenderer that a new frame will be coming soon.
      * Currently only {@link ThreadedRenderer} cares about this, and uses
@@ -1958,60 +1934,7 @@
                 || mAttachInfo.mRecomputeGlobalAttributes;
         if (didLayout) {
             performLayout(lp, desiredWindowWidth, desiredWindowHeight);
-        }
 
-        /*
-         * Handle partial layouts.
-         *
-         * Views that have requested partial layouts will not change size or position
-         * within their parent view, therefore we will re-measure and re-layout each one
-         * after any regularly scheduled layout pass. Any view that already had its
-         * isLayoutRequested bit cleared will be skipped, since this means the view has already
-         * been measured and laid out on this traversal pass naturally. Views won't be added
-         * to this list if layout was already requested when a partial layout is requested
-         * for a view, so there should not be duplicates in the list.
-         */
-        final List<View> partialLayoutViews = mAttachInfo.mPartialLayoutViews;
-        final boolean didPartialLayout;
-        if (!partialLayoutViews.isEmpty()) {
-            // Measurement or layout of views may result in changes to the list
-            // of partial-layout views. Swap in an "empty" list to prevent
-            // concurrent modification of the list being traversed.
-            if (mAttachInfo.mEmptyPartialLayoutViews == null) {
-                mAttachInfo.mPartialLayoutViews = new ArrayList<>();
-            } else {
-                mAttachInfo.mPartialLayoutViews = mAttachInfo.mEmptyPartialLayoutViews;
-            }
-
-            final int count = partialLayoutViews.size();
-            mInLayout = true;
-            for (int i = 0; i < count; i++) {
-                final View view = partialLayoutViews.get(i);
-
-                // Make sure the view is still attached and that it still has layout requested.
-                // We might have already serviced the layout request through the standard full-tree
-                // layout pass above or even through a previous partial layout view in this list.
-                if (view.isAttachedToWindow() && view.isLayoutRequested()) {
-                    final int widthSpec = MeasureSpec.makeMeasureSpec(view.getMeasuredWidth(),
-                            MeasureSpec.EXACTLY);
-                    final int heightSpec = MeasureSpec.makeMeasureSpec(view.getMeasuredHeight(),
-                            MeasureSpec.EXACTLY);
-                    view.measure(widthSpec, heightSpec);
-                    view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
-                }
-            }
-            mInLayout = false;
-            didPartialLayout = true;
-            triggerGlobalLayoutListener = true;
-
-            // The traversal list becomes the new empty list.
-            partialLayoutViews.clear();
-            mAttachInfo.mEmptyPartialLayoutViews = partialLayoutViews;
-        } else {
-            didPartialLayout = false;
-        }
-
-        if (didLayout || didPartialLayout) {
             // By this point all views have been sized and positioned
             // We can compute the transparent area
 
@@ -2041,7 +1964,7 @@
 
             if (DBG) {
                 System.out.println("======================================");
-                System.out.println("performTraversals -- after performLayout/partial layout");
+                System.out.println("performTraversals -- after setFrame");
                 host.debug();
             }
         }
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 3c4d45a..53490b4 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -29,6 +29,7 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.PixelFormat;
+import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.media.session.MediaController;
 import android.net.Uri;
@@ -247,12 +248,30 @@
 
     private static final String PROPERTY_HARDWARE_UI = "persist.sys.ui.hw";
 
+    /**
+     * Flag for letting the theme drive the color of the window caption controls. Use with
+     * {@link #setDecorCaptionShade(int)}. This is the default value.
+     */
+    public static final int DECOR_CAPTION_SHADE_AUTO = 0;
+    /**
+     * Flag for setting light-color controls on the window caption. Use with
+     * {@link #setDecorCaptionShade(int)}.
+     */
+    public static final int DECOR_CAPTION_SHADE_LIGHT = 1;
+    /**
+     * Flag for setting dark-color controls on the window caption. Use with
+     * {@link #setDecorCaptionShade(int)}.
+     */
+    public static final int DECOR_CAPTION_SHADE_DARK = 2;
+
     private final Context mContext;
 
     private TypedArray mWindowStyle;
     private Callback mCallback;
     private OnWindowDismissedCallback mOnWindowDismissedCallback;
     private WindowControllerCallback mWindowControllerCallback;
+    private RestrictedCaptionAreaListener mRestrictedCaptionAreaListener;
+    private Rect mRestrictedCaptionAreaRect;
     private WindowManager mWindowManager;
     private IBinder mAppToken;
     private String mAppName;
@@ -565,6 +584,18 @@
         int getWindowStackId() throws RemoteException;
     }
 
+    /**
+     * Callback for clients that want to be aware of where caption draws content.
+     */
+    public interface RestrictedCaptionAreaListener {
+        /**
+         * Called when the area where caption draws content changes.
+         *
+         * @param rect The area where caption content is positioned, relative to the top view.
+         */
+        void onRestrictedCaptionAreaChanged(Rect rect);
+    }
+
     public Window(Context context) {
         mContext = context;
         mFeatures = mLocalFeatures = getDefaultFeatures(context);
@@ -778,6 +809,16 @@
     }
 
     /**
+     * Set a callback for changes of area where caption will draw its content.
+     *
+     * @param listener Callback that will be called when the area changes.
+     */
+    public final void setRestrictedCaptionAreaListener(RestrictedCaptionAreaListener listener) {
+        mRestrictedCaptionAreaListener = listener;
+        mRestrictedCaptionAreaRect = listener != null ? new Rect() : null;
+    }
+
+    /**
      * Take ownership of this window's surface.  The window's view hierarchy
      * will no longer draw into the surface, though it will otherwise continue
      * to operate (such as for receiving input events).  The given SurfaceHolder
@@ -1158,27 +1199,6 @@
     public abstract void setContentView(View view);
 
     /**
-     * Install a view in the decoration (title) area, to be shown when
-     * the window is in multi-window mode. This view will be placed
-     * next to the window controls.
-     *
-     * The view may be restored to defaults by passing null.
-     *
-     * @param view The desired view to display in window decorations.
-     */
-    public abstract void setDecorView(View view);
-
-    /**
-     * Convenience for
-     * {@link #setDecorView(View)}
-     * to set the custom window decoration from a layout resource. The layout will be inflated
-     * adding all top level views to the decoration
-     *
-     * @param layoutResID Resource ID to be inflated.
-     */
-    public abstract void setDecorView(@LayoutRes int layoutResID);
-
-    /**
      * Set the screen content to an explicit view.  This view is placed
      * directly into the screen's view hierarchy.  It can itself be a complex
      * view hierarchy.
@@ -2060,4 +2080,30 @@
     public boolean getOverlayDecorCaption() {
         return mOverlayWithDecorCaption;
     }
+
+    /** @hide */
+    public void notifyRestrictedCaptionAreaCallback(int left, int top, int right, int bottom) {
+        if (mRestrictedCaptionAreaListener != null) {
+            mRestrictedCaptionAreaRect.set(left, top, right, bottom);
+            mRestrictedCaptionAreaListener.onRestrictedCaptionAreaChanged(
+                    mRestrictedCaptionAreaRect);
+        }
+    }
+
+    /**
+     * Set what color should the caption controls be. By default the system will try to determine
+     * the color from the theme. You can overwrite this by using {@link #DECOR_CAPTION_SHADE_DARK}
+     * or {@link #DECOR_CAPTION_SHADE_DARK}.
+     */
+    public abstract void setDecorCaptionShade(int decorCaptionShade);
+
+    /**
+     * Set the drawable that is drawn underneath the caption during the resizing.
+     *
+     * During the resizing the caption might not be drawn fast enough to match the new dimensions.
+     * There is a second caption drawn underneath it that will be fast enough. By default the
+     * caption is constructed from the theme. You can provide a drawable, that will be drawn instead
+     * to better match your application.
+     */
+    public abstract void setResizingCaptionDrawable(Drawable drawable);
 }
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 7e45bbb..b1a8479 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -431,6 +431,11 @@
         public int getLidState();
 
         /**
+         * Lock the device now.
+         */
+        public void lockDeviceNow();
+
+        /**
          * Returns a code that descripbes whether the camera lens is covered or not.
          */
         public int getCameraLensCoverState();
diff --git a/core/java/android/view/inputmethod/InputMethodSubtype.java b/core/java/android/view/inputmethod/InputMethodSubtype.java
index fbaf51c..a42f4d9 100644
--- a/core/java/android/view/inputmethod/InputMethodSubtype.java
+++ b/core/java/android/view/inputmethod/InputMethodSubtype.java
@@ -16,6 +16,7 @@
 
 package android.view.inputmethod;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -50,6 +51,7 @@
  *
  * @attr ref android.R.styleable#InputMethod_Subtype_label
  * @attr ref android.R.styleable#InputMethod_Subtype_icon
+ * @attr ref android.R.styleable#InputMethod_Subtype_languageTag
  * @attr ref android.R.styleable#InputMethod_Subtype_imeSubtypeLocale
  * @attr ref android.R.styleable#InputMethod_Subtype_imeSubtypeMode
  * @attr ref android.R.styleable#InputMethod_Subtype_imeSubtypeExtraValue
@@ -60,6 +62,7 @@
  */
 public final class InputMethodSubtype implements Parcelable {
     private static final String TAG = InputMethodSubtype.class.getSimpleName();
+    private static final String LANGUAGE_TAG_NONE = "";
     private static final String EXTRA_VALUE_PAIR_SEPARATOR = ",";
     private static final String EXTRA_VALUE_KEY_VALUE_SEPARATOR = "=";
     // TODO: remove this
@@ -74,6 +77,7 @@
     private final int mSubtypeNameResId;
     private final int mSubtypeId;
     private final String mSubtypeLocale;
+    private final String mSubtypeLanguageTag;
     private final String mSubtypeMode;
     private final String mSubtypeExtraValue;
     private volatile HashMap<String, String> mExtraValueHashMapCache;
@@ -171,6 +175,15 @@
         private String mSubtypeLocale = "";
 
         /**
+         * @param languageTag is the BCP-47 Language Tag supported by this subtype.
+         */
+        public InputMethodSubtypeBuilder setLanguageTag(String languageTag) {
+            mSubtypeLanguageTag = languageTag == null ? LANGUAGE_TAG_NONE : languageTag;
+            return this;
+        }
+        private String mSubtypeLanguageTag = LANGUAGE_TAG_NONE;
+
+        /**
          * @param subtypeMode is the mode supported by this subtype.
          */
         public InputMethodSubtypeBuilder setSubtypeMode(String subtypeMode) {
@@ -271,6 +284,7 @@
         mSubtypeNameResId = builder.mSubtypeNameResId;
         mSubtypeIconResId = builder.mSubtypeIconResId;
         mSubtypeLocale = builder.mSubtypeLocale;
+        mSubtypeLanguageTag = builder.mSubtypeLanguageTag;
         mSubtypeMode = builder.mSubtypeMode;
         mSubtypeExtraValue = builder.mSubtypeExtraValue;
         mIsAuxiliary = builder.mIsAuxiliary;
@@ -291,6 +305,8 @@
         s = source.readString();
         mSubtypeLocale = s != null ? s : "";
         s = source.readString();
+        mSubtypeLanguageTag = s != null ? s : LANGUAGE_TAG_NONE;
+        s = source.readString();
         mSubtypeMode = s != null ? s : "";
         s = source.readString();
         mSubtypeExtraValue = s != null ? s : "";
@@ -318,21 +334,38 @@
     /**
      * @return The locale of the subtype. This method returns the "locale" string parameter passed
      * to the constructor.
+     *
+     * @deprecated Use {@link #getLanguageTag()} instead.
      */
+    @Deprecated
+    @NonNull
     public String getLocale() {
         return mSubtypeLocale;
     }
 
     /**
-     * @return The normalized {@link Locale} object of the subtype. The returned locale may or may
-     * not equal to "locale" string parameter passed to the constructor.
+     * @return the BCP-47 Language Tag of the subtype.  Returns an empty string when no Language Tag
+     * is specified.
      *
-     * <p>TODO: Consider to make this a public API.</p>
+     * @see Locale#forLanguageTag(String)
+     */
+    @NonNull
+    public String getLanguageTag() {
+        return mSubtypeLanguageTag;
+    }
+
+    /**
+     * @return {@link Locale} constructed from {@link #getLanguageTag()}. If the Language Tag is not
+     * specified, then try to construct from {@link #getLocale()}
+     *
+     * <p>TODO: Consider to make this a public API, or move this to support lib.</p>
      * @hide
      */
     @Nullable
     public Locale getLocaleObject() {
-        // TODO: Move the following method from InputMethodUtils to InputMethodSubtype.
+        if (!TextUtils.isEmpty(mSubtypeLanguageTag)) {
+            return Locale.forLanguageTag(mSubtypeLanguageTag);
+        }
         return InputMethodUtils.constructLocaleFromString(mSubtypeLocale);
     }
 
@@ -476,13 +509,14 @@
                 return (subtype.hashCode() == hashCode());
             }
             return (subtype.hashCode() == hashCode())
-                && (subtype.getLocale().equals(getLocale()))
-                && (subtype.getMode().equals(getMode()))
-                && (subtype.getExtraValue().equals(getExtraValue()))
-                && (subtype.isAuxiliary() == isAuxiliary())
-                && (subtype.overridesImplicitlyEnabledSubtype()
-                        == overridesImplicitlyEnabledSubtype())
-                && (subtype.isAsciiCapable() == isAsciiCapable());
+                    && (subtype.getLocale().equals(getLocale()))
+                    && (subtype.getLanguageTag().equals(getLanguageTag()))
+                    && (subtype.getMode().equals(getMode()))
+                    && (subtype.getExtraValue().equals(getExtraValue()))
+                    && (subtype.isAuxiliary() == isAuxiliary())
+                    && (subtype.overridesImplicitlyEnabledSubtype()
+                            == overridesImplicitlyEnabledSubtype())
+                    && (subtype.isAsciiCapable() == isAsciiCapable());
         }
         return false;
     }
@@ -497,6 +531,7 @@
         dest.writeInt(mSubtypeNameResId);
         dest.writeInt(mSubtypeIconResId);
         dest.writeString(mSubtypeLocale);
+        dest.writeString(mSubtypeLanguageTag);
         dest.writeString(mSubtypeMode);
         dest.writeString(mSubtypeExtraValue);
         dest.writeInt(mIsAuxiliary ? 1 : 0);
diff --git a/core/java/android/view/textservice/SpellCheckerInfo.java b/core/java/android/view/textservice/SpellCheckerInfo.java
index 2167862..471b6d4 100644
--- a/core/java/android/view/textservice/SpellCheckerInfo.java
+++ b/core/java/android/view/textservice/SpellCheckerInfo.java
@@ -117,7 +117,11 @@
                             a.getString(com.android.internal.R.styleable
                                     .SpellChecker_Subtype_subtypeLocale),
                             a.getString(com.android.internal.R.styleable
-                                    .SpellChecker_Subtype_subtypeExtraValue));
+                                    .SpellChecker_Subtype_languageTag),
+                            a.getString(com.android.internal.R.styleable
+                                    .SpellChecker_Subtype_subtypeExtraValue),
+                            a.getInt(com.android.internal.R.styleable
+                                    .SpellChecker_Subtype_subtypeId, 0));
                     mSubtypes.add(subtype);
                 }
             }
diff --git a/core/java/android/view/textservice/SpellCheckerSubtype.java b/core/java/android/view/textservice/SpellCheckerSubtype.java
index 77fd002..df33698 100644
--- a/core/java/android/view/textservice/SpellCheckerSubtype.java
+++ b/core/java/android/view/textservice/SpellCheckerSubtype.java
@@ -18,6 +18,7 @@
 
 import com.android.internal.inputmethod.InputMethodUtils;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -36,29 +37,68 @@
 /**
  * This class is used to specify meta information of a subtype contained in a spell checker.
  * Subtype can describe locale (e.g. en_US, fr_FR...) used for settings.
+ *
+ * @see SpellCheckerInfo
+ *
+ * @attr ref android.R.styleable#SpellChecker_Subtype_label
+ * @attr ref android.R.styleable#SpellChecker_Subtype_languageTag
+ * @attr ref android.R.styleable#SpellChecker_Subtype_subtypeLocale
+ * @attr ref android.R.styleable#SpellChecker_Subtype_subtypeExtraValue
+ * @attr ref android.R.styleable#SpellChecker_Subtype_subtypeId
  */
 public final class SpellCheckerSubtype implements Parcelable {
     private static final String TAG = SpellCheckerSubtype.class.getSimpleName();
     private static final String EXTRA_VALUE_PAIR_SEPARATOR = ",";
     private static final String EXTRA_VALUE_KEY_VALUE_SEPARATOR = "=";
+    private static final int SUBTYPE_ID_NONE = 0;
+    private static final String SUBTYPE_LANGUAGE_TAG_NONE = "";
 
+    private final int mSubtypeId;
     private final int mSubtypeHashCode;
     private final int mSubtypeNameResId;
     private final String mSubtypeLocale;
+    private final String mSubtypeLanguageTag;
     private final String mSubtypeExtraValue;
     private HashMap<String, String> mExtraValueHashMapCache;
 
     /**
-     * Constructor
+     * Constructor.
+     *
+     * <p>There is no public API that requires developers to instantiate custom
+     * {@link SpellCheckerSubtype} object.  Hence so far there is no need to make this constructor
+     * available in public API.</p>
+     *
+     * @param nameId The name of the subtype
+     * @param locale The locale supported by the subtype
+     * @param languageTag The BCP-47 Language Tag associated with this subtype.
+     * @param extraValue The extra value of the subtype
+     * @param subtypeId The subtype ID that is supposed to be stable during package update.
+     *
+     * @hide
+     */
+    public SpellCheckerSubtype(int nameId, String locale, String languageTag, String extraValue,
+            int subtypeId) {
+        mSubtypeNameResId = nameId;
+        mSubtypeLocale = locale != null ? locale : "";
+        mSubtypeLanguageTag = languageTag != null ? languageTag : SUBTYPE_LANGUAGE_TAG_NONE;
+        mSubtypeExtraValue = extraValue != null ? extraValue : "";
+        mSubtypeId = subtypeId;
+        mSubtypeHashCode = mSubtypeId != SUBTYPE_ID_NONE ?
+                mSubtypeId : hashCodeInternal(mSubtypeLocale, mSubtypeExtraValue);
+    }
+
+    /**
+     * Constructor.
      * @param nameId The name of the subtype
      * @param locale The locale supported by the subtype
      * @param extraValue The extra value of the subtype
+     *
+     * @deprecated There is no public API that requires developers to directly instantiate custom
+     * {@link SpellCheckerSubtype} objects right now.  Hence only the system is expected to be able
+     * to instantiate {@link SpellCheckerSubtype} object.
      */
     public SpellCheckerSubtype(int nameId, String locale, String extraValue) {
-        mSubtypeNameResId = nameId;
-        mSubtypeLocale = locale != null ? locale : "";
-        mSubtypeExtraValue = extraValue != null ? extraValue : "";
-        mSubtypeHashCode = hashCodeInternal(mSubtypeLocale, mSubtypeExtraValue);
+        this(nameId, locale, SUBTYPE_LANGUAGE_TAG_NONE, extraValue, SUBTYPE_ID_NONE);
     }
 
     SpellCheckerSubtype(Parcel source) {
@@ -67,8 +107,12 @@
         s = source.readString();
         mSubtypeLocale = s != null ? s : "";
         s = source.readString();
+        mSubtypeLanguageTag = s != null ? s : "";
+        s = source.readString();
         mSubtypeExtraValue = s != null ? s : "";
-        mSubtypeHashCode = hashCodeInternal(mSubtypeLocale, mSubtypeExtraValue);
+        mSubtypeId = source.readInt();
+        mSubtypeHashCode = mSubtypeId != SUBTYPE_ID_NONE ?
+                mSubtypeId : hashCodeInternal(mSubtypeLocale, mSubtypeExtraValue);
     }
 
     /**
@@ -80,12 +124,27 @@
 
     /**
      * @return the locale of the subtype
+     *
+     * @deprecated Use {@link #getLanguageTag()} instead.
      */
+    @Deprecated
+    @NonNull
     public String getLocale() {
         return mSubtypeLocale;
     }
 
     /**
+     * @return the BCP-47 Language Tag of the subtype.  Returns an empty string when no Language Tag
+     * is specified.
+     *
+     * @see Locale#forLanguageTag(String)
+     */
+    @NonNull
+    public String getLanguageTag() {
+        return mSubtypeLanguageTag;
+    }
+
+    /**
      * @return the extra value of the subtype
      */
     public String getExtraValue() {
@@ -141,23 +200,30 @@
     public boolean equals(Object o) {
         if (o instanceof SpellCheckerSubtype) {
             SpellCheckerSubtype subtype = (SpellCheckerSubtype) o;
+            if (subtype.mSubtypeId != SUBTYPE_ID_NONE || mSubtypeId != SUBTYPE_ID_NONE) {
+                return (subtype.hashCode() == hashCode());
+            }
             return (subtype.hashCode() == hashCode())
-                && (subtype.getNameResId() == getNameResId())
-                && (subtype.getLocale().equals(getLocale()))
-                && (subtype.getExtraValue().equals(getExtraValue()));
+                    && (subtype.getNameResId() == getNameResId())
+                    && (subtype.getLocale().equals(getLocale()))
+                    && (subtype.getLanguageTag().equals(getLanguageTag()))
+                    && (subtype.getExtraValue().equals(getExtraValue()));
         }
         return false;
     }
 
     /**
-     * @return The normalized {@link Locale} object of the subtype. The returned locale may or may
-     * not equal to "locale" string parameter passed to the constructor.
+     * @return {@link Locale} constructed from {@link #getLanguageTag()}. If the Language Tag is not
+     * specified, then try to construct from {@link #getLocale()}
      *
-     * <p>TODO: Consider to make this a public API.</p>
+     * <p>TODO: Consider to make this a public API, or move this to support lib.</p>
      * @hide
      */
     @Nullable
     public Locale getLocaleObject() {
+        if (!TextUtils.isEmpty(mSubtypeLanguageTag)) {
+            return Locale.forLanguageTag(mSubtypeLanguageTag);
+        }
         return InputMethodUtils.constructLocaleFromString(mSubtypeLocale);
     }
 
@@ -196,7 +262,9 @@
     public void writeToParcel(Parcel dest, int parcelableFlags) {
         dest.writeInt(mSubtypeNameResId);
         dest.writeString(mSubtypeLocale);
+        dest.writeString(mSubtypeLanguageTag);
         dest.writeString(mSubtypeExtraValue);
+        dest.writeInt(mSubtypeId);
     }
 
     public static final Parcelable.Creator<SpellCheckerSubtype> CREATOR
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index f050e49..e1ce9fe 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2109,11 +2109,6 @@
     }
 
     @Override
-    public int findDependentLayoutAxes(View child, int axisFilter) {
-        return findDependentLayoutAxesHelper(child, axisFilter, LayoutParams.class);
-    }
-
-    @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         if (mSelector == null) {
             useDefaultSelector();
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index 10aefe4..cf4587d 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -16,6 +16,8 @@
 
 package android.widget;
 
+import com.android.internal.R;
+
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.ColorStateList;
@@ -33,8 +35,6 @@
 import android.view.ViewConfiguration;
 import android.view.accessibility.AccessibilityNodeInfo;
 
-import com.android.internal.R;
-
 public abstract class AbsSeekBar extends ProgressBar {
     private final Rect mTempRect = new Rect();
 
@@ -424,10 +424,10 @@
         if (thumbHeight > trackHeight) {
             final int offsetHeight = (paddedHeight - thumbHeight) / 2;
             trackOffset = offsetHeight + (thumbHeight - trackHeight) / 2;
-            thumbOffset = offsetHeight + 0;
+            thumbOffset = offsetHeight;
         } else {
             final int offsetHeight = (paddedHeight - trackHeight) / 2;
-            trackOffset = offsetHeight + 0;
+            trackOffset = offsetHeight;
             thumbOffset = offsetHeight + (trackHeight - thumbHeight) / 2;
         }
 
@@ -574,13 +574,7 @@
                 if (isInScrollingContainer()) {
                     mTouchDownX = event.getX();
                 } else {
-                    setPressed(true);
-                    if (mThumb != null) {
-                        invalidate(mThumb.getBounds()); // This may be within the padding region
-                    }
-                    onStartTrackingTouch();
-                    trackTouchEvent(event);
-                    attemptClaimDrag();
+                    startDrag(event);
                 }
                 break;
 
@@ -590,13 +584,7 @@
                 } else {
                     final float x = event.getX();
                     if (Math.abs(x - mTouchDownX) > mScaledTouchSlop) {
-                        setPressed(true);
-                        if (mThumb != null) {
-                            invalidate(mThumb.getBounds()); // This may be within the padding region
-                        }
-                        onStartTrackingTouch();
-                        trackTouchEvent(event);
-                        attemptClaimDrag();
+                        startDrag(event);
                     }
                 }
                 break;
@@ -630,6 +618,19 @@
         return true;
     }
 
+    private void startDrag(MotionEvent event) {
+        setPressed(true);
+
+        if (mThumb != null) {
+            // This may be within the padding region.
+            invalidate(mThumb.getBounds());
+        }
+
+        onStartTrackingTouch();
+        trackTouchEvent(event);
+        attemptClaimDrag();
+    }
+
     private void setHotspot(float x, float y) {
         final Drawable bg = getBackground();
         if (bg != null) {
@@ -638,18 +639,20 @@
     }
 
     private void trackTouchEvent(MotionEvent event) {
+        final int x = Math.round(event.getX());
+        final int y = Math.round(event.getY());
         final int width = getWidth();
-        final int available = width - mPaddingLeft - mPaddingRight;
-        final int x = (int) event.getX();
-        float scale;
-        float progress = 0;
+        final int availableWidth = width - mPaddingLeft - mPaddingRight;
+
+        final float scale;
+        float progress = 0.0f;
         if (isLayoutRtl() && mMirrorForRtl) {
             if (x > width - mPaddingRight) {
                 scale = 0.0f;
             } else if (x < mPaddingLeft) {
                 scale = 1.0f;
             } else {
-                scale = (float)(available - x + mPaddingLeft) / (float)available;
+                scale = (availableWidth - x + mPaddingLeft) / (float) availableWidth;
                 progress = mTouchProgressOffset;
             }
         } else {
@@ -658,15 +661,16 @@
             } else if (x > width - mPaddingRight) {
                 scale = 1.0f;
             } else {
-                scale = (float)(x - mPaddingLeft) / (float)available;
+                scale = (x - mPaddingLeft) / (float) availableWidth;
                 progress = mTouchProgressOffset;
             }
         }
+
         final int max = getMax();
         progress += scale * max;
 
-        setHotspot(x, (int) event.getY());
-        setProgressInternal((int) progress, true, false);
+        setHotspot(x, y);
+        setProgressInternal(Math.round(progress), true, false);
     }
 
     /**
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 5146bc6..2d1f855 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -75,6 +75,7 @@
 import android.view.DisplayListCanvas;
 import android.view.DragEvent;
 import android.view.Gravity;
+import android.view.InputDevice;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuItem;
@@ -229,7 +230,14 @@
     // Set when this TextView gained focus with some text selected. Will start selection mode.
     boolean mCreatedWithASelection;
 
-    boolean mDoubleTap = false;
+    // Indicates the current tap state (first tap, double tap, or triple click).
+    private int mTapState = TAP_STATE_INITIAL;
+    private long mLastTouchUpTime = 0;
+    private static final int TAP_STATE_INITIAL = 0;
+    private static final int TAP_STATE_FIRST_TAP = 1;
+    private static final int TAP_STATE_DOUBLE_TAP = 2;
+    // Only for mouse input.
+    private static final int TAP_STATE_TRIPLE_CLICK = 3;
 
     private Runnable mInsertionActionModeRunnable;
 
@@ -769,20 +777,12 @@
         return retOffset;
     }
 
-    /**
-     * Adjusts selection to the word under last touch offset. Return true if the operation was
-     * successfully performed.
-     */
-    private boolean selectCurrentWord() {
-        if (!mTextView.canSelectText()) {
-            return false;
-        }
-
+    private boolean needsToSelectAllToSelectWordOrParagraph() {
         if (mTextView.hasPasswordTransformationMethod()) {
             // Always select all on a password field.
             // Cut/copy menu entries are not available for passwords, but being able to select all
             // is however useful to delete or paste to replace the entire content.
-            return mTextView.selectAllText();
+            return true;
         }
 
         int inputType = mTextView.getInputType();
@@ -797,6 +797,21 @@
                 variation == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS ||
                 variation == InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS ||
                 variation == InputType.TYPE_TEXT_VARIATION_FILTER) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Adjusts selection to the word under last touch offset. Return true if the operation was
+     * successfully performed.
+     */
+    private boolean selectCurrentWord() {
+        if (!mTextView.canSelectText()) {
+            return false;
+        }
+
+        if (needsToSelectAllToSelectWordOrParagraph()) {
             return mTextView.selectAllText();
         }
 
@@ -805,8 +820,8 @@
         final int maxOffset = TextUtils.unpackRangeEndFromLong(lastTouchOffsets);
 
         // Safety check in case standard touch event handling has been bypassed
-        if (minOffset < 0 || minOffset >= mTextView.getText().length()) return false;
-        if (maxOffset < 0 || maxOffset >= mTextView.getText().length()) return false;
+        if (minOffset < 0 || minOffset > mTextView.getText().length()) return false;
+        if (maxOffset < 0 || maxOffset > mTextView.getText().length()) return false;
 
         int selectionStart, selectionEnd;
 
@@ -839,6 +854,63 @@
         return selectionEnd > selectionStart;
     }
 
+    /**
+     * Adjusts selection to the paragraph under last touch offset. Return true if the operation was
+     * successfully performed.
+     */
+    private boolean selectCurrentParagraph() {
+        if (!mTextView.canSelectText()) {
+            return false;
+        }
+
+        if (needsToSelectAllToSelectWordOrParagraph()) {
+            return mTextView.selectAllText();
+        }
+
+        long lastTouchOffsets = getLastTouchOffsets();
+        final int minLastTouchOffset = TextUtils.unpackRangeStartFromLong(lastTouchOffsets);
+        final int maxLastTouchOffset = TextUtils.unpackRangeEndFromLong(lastTouchOffsets);
+
+        final long paragraphsRange = getParagraphsRange(minLastTouchOffset, maxLastTouchOffset);
+        final int start = TextUtils.unpackRangeStartFromLong(paragraphsRange);
+        final int end = TextUtils.unpackRangeEndFromLong(paragraphsRange);
+        if (start < end) {
+            Selection.setSelection((Spannable) mTextView.getText(), start, end);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Get the minimum range of paragraphs that contains startOffset and endOffset.
+     */
+    private long getParagraphsRange(int startOffset, int endOffset) {
+        final Layout layout = mTextView.getLayout();
+        if (layout == null) {
+            return TextUtils.packRangeInLong(-1, -1);
+        }
+        final CharSequence text = mTextView.getText();
+        int minLine = layout.getLineForOffset(startOffset);
+        // Search paragraph start.
+        while (minLine > 0) {
+            final int prevLineEndOffset = layout.getLineEnd(minLine - 1);
+            if (text.charAt(prevLineEndOffset - 1) == '\n') {
+                break;
+            }
+            minLine--;
+        }
+        int maxLine = layout.getLineForOffset(endOffset);
+        // Search paragraph end.
+        while (maxLine < layout.getLineCount() - 1) {
+            final int lineEndOffset = layout.getLineEnd(maxLine);
+            if (text.charAt(lineEndOffset - 1) == '\n') {
+                break;
+            }
+            maxLine++;
+        }
+        return TextUtils.packRangeInLong(layout.getLineStart(minLine), layout.getLineEnd(maxLine));
+    }
+
     void onLocaleChanged() {
         // Will be re-created on demand in getWordIterator with the proper new locale
         mWordIterator = null;
@@ -1219,7 +1291,31 @@
         }
     }
 
+    private void updateTapState(MotionEvent event) {
+        final int action = event.getActionMasked();
+        if (action == MotionEvent.ACTION_DOWN) {
+            final boolean isMouse = event.isFromSource(InputDevice.SOURCE_MOUSE);
+            // Detect double tap and triple click.
+            if (((mTapState == TAP_STATE_FIRST_TAP)
+                    || ((mTapState == TAP_STATE_DOUBLE_TAP) && isMouse))
+                        && (SystemClock.uptimeMillis() - mLastTouchUpTime) <=
+                                ViewConfiguration.getDoubleTapTimeout()) {
+                if (mTapState == TAP_STATE_FIRST_TAP) {
+                    mTapState = TAP_STATE_DOUBLE_TAP;
+                } else {
+                    mTapState = TAP_STATE_TRIPLE_CLICK;
+                }
+            } else {
+                mTapState = TAP_STATE_FIRST_TAP;
+            }
+        }
+        if (action == MotionEvent.ACTION_UP) {
+            mLastTouchUpTime = SystemClock.uptimeMillis();
+        }
+    }
+
     void onTouchEvent(MotionEvent event) {
+        updateTapState(event);
         updateFloatingToolbarVisibility(event);
 
         if (hasSelectionController()) {
@@ -1773,7 +1869,8 @@
         stopTextActionMode();
         mPreserveDetachedSelection = false;
 
-        getSelectionController().enterDrag();
+        getSelectionController().enterDrag(
+                SelectionModifierCursorController.DRAG_ACCELERATOR_MODE_WORD);
         return true;
     }
 
@@ -3777,30 +3874,6 @@
             }
         }
 
-        public void showAtLocation(int offset) {
-            // TODO - investigate if there's a better way to show the handles
-            // after the drag accelerator has occured.
-            int[] tmpCords = new int[2];
-            mTextView.getLocationInWindow(tmpCords);
-
-            Layout layout = mTextView.getLayout();
-            int posX = tmpCords[0];
-            int posY = tmpCords[1];
-
-            final int line = layout.getLineForOffset(offset);
-
-            int startX = (int) (layout.getPrimaryHorizontal(offset) - 0.5f
-                    - mHotspotX - getHorizontalOffset() + getCursorOffset());
-            int startY = layout.getLineBottom(line);
-
-            // Take TextView's padding and scroll into account.
-            startX += mTextView.viewportToContentHorizontalOffset();
-            startY += mTextView.viewportToContentVerticalOffset();
-
-            mContainer.showAtLocation(mTextView, Gravity.NO_GRAVITY,
-                    startX + posX, startY + posY);
-        }
-
         @Override
         protected void onDraw(Canvas c) {
             final int drawWidth = mDrawable.getIntrinsicWidth();
@@ -3933,13 +4006,16 @@
 
             // Cancel the single tap delayed runnable.
             if (mInsertionActionModeRunnable != null
-                    && (mDoubleTap || isCursorInsideEasyCorrectionSpan())) {
+                    && ((mTapState == TAP_STATE_DOUBLE_TAP)
+                            || (mTapState == TAP_STATE_TRIPLE_CLICK)
+                            || isCursorInsideEasyCorrectionSpan())) {
                 mTextView.removeCallbacks(mInsertionActionModeRunnable);
             }
 
             // Prepare and schedule the single tap runnable to run exactly after the double tap
             // timeout has passed.
-            if (!mDoubleTap && !isCursorInsideEasyCorrectionSpan()
+            if ((mTapState != TAP_STATE_DOUBLE_TAP) && (mTapState != TAP_STATE_TRIPLE_CLICK)
+                    && !isCursorInsideEasyCorrectionSpan()
                     && (durationSinceCutOrCopy < RECENT_CUT_COPY_DURATION)) {
                 if (mTextActionMode == null) {
                     if (mInsertionActionModeRunnable == null) {
@@ -4223,10 +4299,15 @@
 
             boolean isExpanding;
             final float xDiff = x - mPrevX;
-            if (atRtl == isStartHandle()) {
-                isExpanding = xDiff > 0 || currLine > mPreviousLineTouched;
+            if (isStartHandle()) {
+                isExpanding = currLine < mPreviousLineTouched;
             } else {
-                isExpanding = xDiff < 0 || currLine < mPreviousLineTouched;
+                isExpanding = currLine > mPreviousLineTouched;
+            }
+            if (atRtl == isStartHandle()) {
+                isExpanding |= xDiff > 0;
+            } else {
+                isExpanding |= xDiff < 0;
             }
 
             if (mTextView.getHorizontallyScrolling()) {
@@ -4492,14 +4573,24 @@
 
         // Where the user first starts the drag motion.
         private int mStartOffset = -1;
-        // Indicates whether the user is selecting text and using the drag accelerator.
-        private boolean mDragAcceleratorActive;
+
         private boolean mHaventMovedEnoughToStartDrag;
         // The line that a selection happened most recently with the drag accelerator.
         private int mLineSelectionIsOn = -1;
         // Whether the drag accelerator has selected past the initial line.
         private boolean mSwitchedLines = false;
 
+        // Indicates the drag accelerator mode that the user is currently using.
+        private int mDragAcceleratorMode = DRAG_ACCELERATOR_MODE_INACTIVE;
+        // Drag accelerator is inactive.
+        private static final int DRAG_ACCELERATOR_MODE_INACTIVE = 0;
+        // Character based selection by dragging. Only for mouse.
+        private static final int DRAG_ACCELERATOR_MODE_CHARACTER = 1;
+        // Word based selection by dragging. Enabled after long pressing or double tapping.
+        private static final int DRAG_ACCELERATOR_MODE_WORD = 2;
+        // Paragraph based selection by dragging. Enabled after mouse triple click.
+        private static final int DRAG_ACCELERATOR_MODE_PARAGRAPH = 3;
+
         SelectionModifierCursorController() {
             resetTouchOffsets();
         }
@@ -4510,7 +4601,6 @@
             }
             initDrawables();
             initHandles();
-            hideInsertionPointCursorController();
         }
 
         private void initDrawables() {
@@ -4548,10 +4638,10 @@
             if (mEndHandle != null) mEndHandle.hide();
         }
 
-        public void enterDrag() {
+        public void enterDrag(int dragAcceleratorMode) {
             // Just need to init the handles / hide insertion cursor.
             show();
-            mDragAcceleratorActive = true;
+            mDragAcceleratorMode = dragAcceleratorMode;
             // Start location of selection.
             mStartOffset = mTextView.getOffsetForPosition(mLastDownPositionX,
                     mLastDownPositionY);
@@ -4563,6 +4653,7 @@
             // the user to continue dragging across the screen to select text; TextView will
             // scroll as necessary.
             mTextView.getParent().requestDisallowInterceptTouchEvent(true);
+            mTextView.cancelLongPress();
         }
 
         public void onTouchEvent(MotionEvent event) {
@@ -4570,6 +4661,7 @@
             // selection and tap can move cursor from this tap position.
             final float eventX = event.getX();
             final float eventY = event.getY();
+            final boolean isMouse = event.isFromSource(InputDevice.SOURCE_MOUSE);
             switch (event.getActionMasked()) {
                 case MotionEvent.ACTION_DOWN:
                     if (extractedTextModeWillBeStarted()) {
@@ -4582,7 +4674,8 @@
 
                         // Double tap detection
                         if (mGestureStayedInTapRegion) {
-                            if (mDoubleTap) {
+                            if (mTapState == TAP_STATE_DOUBLE_TAP
+                                    || mTapState == TAP_STATE_TRIPLE_CLICK) {
                                 final float deltaX = eventX - mDownPositionX;
                                 final float deltaY = eventY - mDownPositionY;
                                 final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
@@ -4593,8 +4686,12 @@
                                 boolean stayedInArea =
                                         distanceSquared < doubleTapSlop * doubleTapSlop;
 
-                                if (stayedInArea && isPositionOnText(eventX, eventY)) {
-                                    selectCurrentWordAndStartDrag();
+                                if (stayedInArea && (isMouse || isPositionOnText(eventX, eventY))) {
+                                    if (mTapState == TAP_STATE_DOUBLE_TAP) {
+                                        selectCurrentWordAndStartDrag();
+                                    } else if (mTapState == TAP_STATE_TRIPLE_CLICK) {
+                                        selectCurrentParagraphAndStartDrag();
+                                    }
                                     mDiscardNextActionUp = true;
                                 }
                             }
@@ -4639,94 +4736,168 @@
                         }
                     }
 
+                    if (isMouse && !isDragAcceleratorActive()) {
+                        final int offset = mTextView.getOffsetForPosition(eventX, eventY);
+                        if (mStartOffset != offset) {
+                            // Start character based drag accelerator.
+                            if (mTextActionMode != null) {
+                                mTextActionMode.finish();
+                            }
+                            enterDrag(DRAG_ACCELERATOR_MODE_CHARACTER);
+                            mDiscardNextActionUp = true;
+                            mHaventMovedEnoughToStartDrag = false;
+                        }
+                    }
+
                     if (mStartHandle != null && mStartHandle.isShowing()) {
                         // Don't do the drag if the handles are showing already.
                         break;
                     }
 
-                    if (mStartOffset != -1 && mTextView.getLayout() != null) {
-                        if (!mHaventMovedEnoughToStartDrag) {
-
-                            float y = eventY;
-                            if (mSwitchedLines) {
-                                // Offset the finger by the same vertical offset as the handles.
-                                // This improves visibility of the content being selected by
-                                // shifting the finger below the content, this is applied once
-                                // the user has switched lines.
-                                final float fingerOffset = (mStartHandle != null)
-                                        ? mStartHandle.getIdealVerticalOffset()
-                                        : touchSlop;
-                                y = eventY - fingerOffset;
-                            }
-
-                            final int currLine = getCurrentLineAdjustedForSlop(
-                                    mTextView.getLayout(),
-                                    mLineSelectionIsOn, y);
-                            if (!mSwitchedLines && currLine != mLineSelectionIsOn) {
-                                // Break early here, we want to offset the finger position from
-                                // the selection highlight, once the user moved their finger
-                                // to a different line we should apply the offset and *not* switch
-                                // lines until recomputing the position with the finger offset.
-                                mSwitchedLines = true;
-                                break;
-                            }
-
-                            int startOffset;
-                            int offset = mTextView.getOffsetAtCoordinate(currLine, eventX);
-                            // Snap to word boundaries.
-                            if (mStartOffset < offset) {
-                                // Expanding with end handle.
-                                offset = getWordEnd(offset);
-                                startOffset = getWordStart(mStartOffset);
-                            } else {
-                                // Expanding with start handle.
-                                offset = getWordStart(offset);
-                                startOffset = getWordEnd(mStartOffset);
-                            }
-                            mLineSelectionIsOn = currLine;
-                            Selection.setSelection((Spannable) mTextView.getText(),
-                                    startOffset, offset);
-                        }
-                    }
+                    updateSelection(event);
                     break;
 
                 case MotionEvent.ACTION_UP:
-                    if (mDragAcceleratorActive) {
-                        // No longer dragging to select text, let the parent intercept events.
-                        mTextView.getParent().requestDisallowInterceptTouchEvent(false);
-
-                        show();
-                        int startOffset = mTextView.getSelectionStart();
-                        int endOffset = mTextView.getSelectionEnd();
-
-                        // Since we don't let drag handles pass once they're visible, we need to
-                        // make sure the start / end locations are correct because the user *can*
-                        // switch directions during the initial drag.
-                        if (endOffset < startOffset) {
-                            int tmp = endOffset;
-                            endOffset = startOffset;
-                            startOffset = tmp;
-
-                            // Also update the selection with the right offsets in this case.
-                            Selection.setSelection((Spannable) mTextView.getText(),
-                                    startOffset, endOffset);
-                        }
-
-                        // Need to do this to display the handles.
-                        mStartHandle.showAtLocation(startOffset);
-                        mEndHandle.showAtLocation(endOffset);
-
-                        // No longer the first dragging motion, reset.
-                        startSelectionActionMode();
-
-                        mDragAcceleratorActive = false;
-                        mStartOffset = -1;
-                        mSwitchedLines = false;
+                    if (!isDragAcceleratorActive()) {
+                        break;
                     }
+                    updateSelection(event);
+
+                    // No longer dragging to select text, let the parent intercept events.
+                    mTextView.getParent().requestDisallowInterceptTouchEvent(false);
+
+                    int startOffset = mTextView.getSelectionStart();
+                    int endOffset = mTextView.getSelectionEnd();
+
+                    // Since we don't let drag handles pass once they're visible, we need to
+                    // make sure the start / end locations are correct because the user *can*
+                    // switch directions during the initial drag.
+                    if (endOffset < startOffset) {
+                        int tmp = endOffset;
+                        endOffset = startOffset;
+                        startOffset = tmp;
+
+                        // Also update the selection with the right offsets in this case.
+                        Selection.setSelection((Spannable) mTextView.getText(),
+                                startOffset, endOffset);
+                    }
+                    if (startOffset != endOffset) {
+                        startSelectionActionMode();
+                    }
+
+                    // No longer the first dragging motion, reset.
+                    resetDragAcceleratorState();
                     break;
             }
         }
 
+        private void updateSelection(MotionEvent event) {
+            if (mTextView.getLayout() != null) {
+                switch (mDragAcceleratorMode) {
+                    case DRAG_ACCELERATOR_MODE_CHARACTER:
+                        updateCharacterBasedSelection(event);
+                        break;
+                    case DRAG_ACCELERATOR_MODE_WORD:
+                        updateWordBasedSelection(event);
+                        break;
+                    case DRAG_ACCELERATOR_MODE_PARAGRAPH:
+                        updateParagraphBasedSelection(event);
+                        break;
+                }
+            }
+        }
+
+        /**
+         * If the TextView allows text selection, selects the current paragraph and starts a drag.
+         *
+         * @return true if the drag was started.
+         */
+        private boolean selectCurrentParagraphAndStartDrag() {
+            if (mInsertionActionModeRunnable != null) {
+                mTextView.removeCallbacks(mInsertionActionModeRunnable);
+            }
+            if (mTextActionMode != null) {
+                mTextActionMode.finish();
+            }
+            if (!selectCurrentParagraph()) {
+                return false;
+            }
+            enterDrag(SelectionModifierCursorController.DRAG_ACCELERATOR_MODE_PARAGRAPH);
+            return true;
+        }
+
+        private void updateCharacterBasedSelection(MotionEvent event) {
+            final int offset = mTextView.getOffsetForPosition(event.getX(), event.getY());
+            Selection.setSelection((Spannable) mTextView.getText(), mStartOffset, offset);
+        }
+
+        private void updateWordBasedSelection(MotionEvent event) {
+            if (mHaventMovedEnoughToStartDrag) {
+                return;
+            }
+            final boolean isMouse = event.isFromSource(InputDevice.SOURCE_MOUSE);
+            final ViewConfiguration viewConfig = ViewConfiguration.get(
+                    mTextView.getContext());
+            final float eventX = event.getX();
+            final float eventY = event.getY();
+            final int currLine;
+            if (isMouse) {
+                // No need to offset the y coordinate for mouse input.
+                currLine = mTextView.getLineAtCoordinate(eventY);
+            } else {
+                float y = eventY;
+                if (mSwitchedLines) {
+                    // Offset the finger by the same vertical offset as the handles.
+                    // This improves visibility of the content being selected by
+                    // shifting the finger below the content, this is applied once
+                    // the user has switched lines.
+                    final int touchSlop = viewConfig.getScaledTouchSlop();
+                    final float fingerOffset = (mStartHandle != null)
+                            ? mStartHandle.getIdealVerticalOffset()
+                            : touchSlop;
+                    y = eventY - fingerOffset;
+                }
+
+                currLine = getCurrentLineAdjustedForSlop(mTextView.getLayout(), mLineSelectionIsOn,
+                        y);
+                if (!mSwitchedLines && currLine != mLineSelectionIsOn) {
+                    // Break early here, we want to offset the finger position from
+                    // the selection highlight, once the user moved their finger
+                    // to a different line we should apply the offset and *not* switch
+                    // lines until recomputing the position with the finger offset.
+                    mSwitchedLines = true;
+                    return;
+                }
+            }
+
+            int startOffset;
+            int offset = mTextView.getOffsetAtCoordinate(currLine, eventX);
+            // Snap to word boundaries.
+            if (mStartOffset < offset) {
+                // Expanding with end handle.
+                offset = getWordEnd(offset);
+                startOffset = getWordStart(mStartOffset);
+            } else {
+                // Expanding with start handle.
+                offset = getWordStart(offset);
+                startOffset = getWordEnd(mStartOffset);
+            }
+            mLineSelectionIsOn = currLine;
+            Selection.setSelection((Spannable) mTextView.getText(),
+                    startOffset, offset);
+        }
+
+        private void updateParagraphBasedSelection(MotionEvent event) {
+            final int offset = mTextView.getOffsetForPosition(event.getX(), event.getY());
+
+            final int start = Math.min(offset, mStartOffset);
+            final int end = Math.max(offset, mStartOffset);
+            final long paragraphsRange = getParagraphsRange(start, end);
+            final int selectionStart = TextUtils.unpackRangeStartFromLong(paragraphsRange);
+            final int selectionEnd = TextUtils.unpackRangeEndFromLong(paragraphsRange);
+            Selection.setSelection((Spannable) mTextView.getText(), selectionStart, selectionEnd);
+        }
+
         /**
          * @param event
          */
@@ -4749,8 +4920,12 @@
 
         public void resetTouchOffsets() {
             mMinTouchOffset = mMaxTouchOffset = -1;
+            resetDragAcceleratorState();
+        }
+
+        private void resetDragAcceleratorState() {
             mStartOffset = -1;
-            mDragAcceleratorActive = false;
+            mDragAcceleratorMode = DRAG_ACCELERATOR_MODE_INACTIVE;
             mSwitchedLines = false;
         }
 
@@ -4765,7 +4940,7 @@
          * @return true if the user is selecting text using the drag accelerator.
          */
         public boolean isDragAcceleratorActive() {
-            return mDragAcceleratorActive;
+            return mDragAcceleratorMode != DRAG_ACCELERATOR_MODE_INACTIVE;
         }
 
         public void onTouchModeChanged(boolean isInTouchMode) {
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index 4d9f55c..280ff15 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -21,8 +21,12 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.res.ColorStateList;
 import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.PorterDuff;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.view.Gravity;
@@ -32,6 +36,9 @@
 import android.view.ViewHierarchyEncoder;
 import android.widget.RemoteViews.RemoteView;
 
+import com.android.internal.R;
+
+
 /**
  * FrameLayout is designed to block out an area on the screen to display
  * a single item. Generally, FrameLayout should be used to hold a single child view, because it can
@@ -164,10 +171,6 @@
             mPaddingBottom + mForegroundPaddingBottom;
     }
 
-    @Override
-    public int findDependentLayoutAxes(View child, int axisFilter) {
-        return findDependentLayoutAxesHelper(child, axisFilter, LayoutParams.class);
-    }
 
     /**
      * {@inheritDoc}
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index ba868a1..ad939be 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -16,7 +16,6 @@
 
 package android.widget;
 
-import android.view.ViewParent;
 import com.android.internal.R;
 
 import android.annotation.IntDef;
@@ -38,8 +37,6 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 
 /**
  * A Layout that arranges its children in a single column or a single row. The direction of 
@@ -647,60 +644,6 @@
         }
     }
 
-    @Override
-    public int findDependentLayoutAxes(View child, int axisFilter) {
-        // This implementation is almost exactly equivalent to the default implementation
-        // offered to the rest of the framework in ViewGroup, but we treat weight to be
-        // functionally equivalent to MATCH_PARENT along the orientation axis.
-
-        if (!checkPartialLayoutParams(child, LayoutParams.class)) return axisFilter;
-        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-        if (child.didLayoutParamsChange()) {
-            // Anything could have changed about our previous assumptions.
-            return axisFilter;
-        }
-
-        // Our layout can always end up depending on a WRAP_CONTENT child.
-        final int wrapAxisFilter = ((lp.width == WRAP_CONTENT ? FLAG_LAYOUT_AXIS_HORIZONTAL : 0)
-                | (lp.height == WRAP_CONTENT ? FLAG_LAYOUT_AXIS_VERTICAL : 0)) & axisFilter;
-
-        if (wrapAxisFilter == axisFilter) {
-            // We know all queried axes are affected, just return early.
-            return wrapAxisFilter;
-        }
-
-        // Our layout *may* depend on a MATCH_PARENT child, depending on whether we can determine
-        // that our layout will remain stable within our parent. We need to ask.
-        int matchAxisFilter = ((lp.width == MATCH_PARENT ? FLAG_LAYOUT_AXIS_HORIZONTAL : 0)
-                | (lp.height == MATCH_PARENT ? FLAG_LAYOUT_AXIS_VERTICAL : 0)) & axisFilter;
-
-        // For LinearLayout, a nonzero weight is equivalent to MATCH_PARENT for this purpose.
-        if (lp.weight > 0) {
-            if (mOrientation == HORIZONTAL) {
-                matchAxisFilter |= FLAG_LAYOUT_AXIS_HORIZONTAL & axisFilter;
-            } else {
-                matchAxisFilter |= FLAG_LAYOUT_AXIS_VERTICAL & axisFilter;
-            }
-        }
-
-        if (matchAxisFilter != 0) {
-            final ViewParent parent = getParent();
-            if (parent != null) {
-                // If our parent depends on us for an axis, then our layout can also be affected
-                // by a MATCH_PARENT child along that axis.
-                return getParent().findDependentLayoutAxes(this, matchAxisFilter)
-                        | wrapAxisFilter;
-            }
-
-            // If we don't have a parent, assume we're affected
-            // in any determined affected direction.
-            return matchAxisFilter | wrapAxisFilter;
-        }
-
-        // Two exact sizes and LayoutParams didn't change. We're safe.
-        return 0;
-    }
-
     /**
      * Determines where to position dividers between children.
      *
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index b43ea76..53ca6d1 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1158,7 +1158,7 @@
             final View child = obtainView(0, mIsScrap);
 
             // Lay out child directly against the parent measure spec so that
-            // we can obtain expected minimum width and height.
+            // we can obtain exected minimum width and height.
             measureScrapChild(child, 0, widthMeasureSpec, heightSize);
 
             childWidth = child.getMeasuredWidth();
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 56513a3..5574f86 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -17,7 +17,6 @@
 package android.widget;
 
 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
-
 import android.R;
 import android.annotation.ColorInt;
 import android.annotation.DrawableRes;
@@ -115,6 +114,7 @@
 import android.view.DragEvent;
 import android.view.Gravity;
 import android.view.HapticFeedbackConstants;
+import android.view.InputDevice;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
@@ -618,9 +618,6 @@
     private final Paint mHighlightPaint;
     private boolean mHighlightPathBogus = true;
 
-    private boolean mFirstTouch = false;
-    private long mLastTouchUpTime = 0;
-
     // Although these fields are specific to editable text, they are not added to Editor because
     // they are defined by the TextView's style and are theme-dependent.
     int mCursorDrawableRes;
@@ -6814,11 +6811,10 @@
 
         if (mEllipsize == TextUtils.TruncateAt.MARQUEE) {
             if (!compressText(ellipsisWidth)) {
+                final int height = mLayoutParams.height;
                 // If the size of the view does not depend on the size of the text, try to
                 // start the marquee immediately
-                final ViewParent parent = getParent();
-                if (parent != null && parent.findDependentLayoutAxes(this,
-                        ViewParent.FLAG_LAYOUT_AXIS_VERTICAL) == 0) {
+                if (height != LayoutParams.WRAP_CONTENT && height != LayoutParams.MATCH_PARENT) {
                     startMarquee();
                 } else {
                     // Defer the start of the marquee until we know our width (see setFrame())
@@ -7217,9 +7213,37 @@
      * new view layout.
      */
     private void checkForResize() {
-        // Always request a layout. The parent will perform the correct version
-        // of the intended optimizations as part of requestLayoutForChild.
-        requestLayout();
+        boolean sizeChanged = false;
+
+        if (mLayout != null) {
+            // Check if our width changed
+            if (mLayoutParams.width == LayoutParams.WRAP_CONTENT) {
+                sizeChanged = true;
+                invalidate();
+            }
+
+            // Check if our height changed
+            if (mLayoutParams.height == LayoutParams.WRAP_CONTENT) {
+                int desiredHeight = getDesiredHeight();
+
+                if (desiredHeight != this.getHeight()) {
+                    sizeChanged = true;
+                }
+            } else if (mLayoutParams.height == LayoutParams.MATCH_PARENT) {
+                if (mDesiredHeightAtMeasure >= 0) {
+                    int desiredHeight = getDesiredHeight();
+
+                    if (desiredHeight != mDesiredHeightAtMeasure) {
+                        sizeChanged = true;
+                    }
+                }
+            }
+        }
+
+        if (sizeChanged) {
+            requestLayout();
+            // caller will have already invalidated
+        }
     }
 
     /**
@@ -7227,11 +7251,56 @@
      * or merely a new text layout.
      */
     private void checkForRelayout() {
-        // Always request a layout. The parent will perform the correct version
-        // of the intended optimizations as part of requestLayoutForChild.
-        nullLayouts();
-        requestLayout();
-        invalidate();
+        // If we have a fixed width, we can just swap in a new text layout
+        // if the text height stays the same or if the view height is fixed.
+
+        if ((mLayoutParams.width != LayoutParams.WRAP_CONTENT ||
+                (mMaxWidthMode == mMinWidthMode && mMaxWidth == mMinWidth)) &&
+                (mHint == null || mHintLayout != null) &&
+                (mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight() > 0)) {
+            // Static width, so try making a new text layout.
+
+            int oldht = mLayout.getHeight();
+            int want = mLayout.getWidth();
+            int hintWant = mHintLayout == null ? 0 : mHintLayout.getWidth();
+
+            /*
+             * No need to bring the text into view, since the size is not
+             * changing (unless we do the requestLayout(), in which case it
+             * will happen at measure).
+             */
+            makeNewLayout(want, hintWant, UNKNOWN_BORING, UNKNOWN_BORING,
+                          mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight(),
+                          false);
+
+            if (mEllipsize != TextUtils.TruncateAt.MARQUEE) {
+                // In a fixed-height view, so use our new text layout.
+                if (mLayoutParams.height != LayoutParams.WRAP_CONTENT &&
+                    mLayoutParams.height != LayoutParams.MATCH_PARENT) {
+                    invalidate();
+                    return;
+                }
+
+                // Dynamic height, but height has stayed the same,
+                // so use our new text layout.
+                if (mLayout.getHeight() == oldht &&
+                    (mHintLayout == null || mHintLayout.getHeight() == oldht)) {
+                    invalidate();
+                    return;
+                }
+            }
+
+            // We lose: the height has changed and we have a dynamic height.
+            // Request a new view layout using our new text layout.
+            requestLayout();
+            invalidate();
+        } else {
+            // Dynamic width, so we have no choice but to request a new
+            // view layout with a new text layout.
+            nullLayouts();
+            requestLayout();
+            invalidate();
+        }
     }
 
     @Override
@@ -8334,23 +8403,6 @@
     @Override
     public boolean onTouchEvent(MotionEvent event) {
         final int action = event.getActionMasked();
-
-        if (mEditor != null && action == MotionEvent.ACTION_DOWN) {
-            // Detect double tap and inform the Editor.
-            if (mFirstTouch && (SystemClock.uptimeMillis() - mLastTouchUpTime) <=
-                    ViewConfiguration.getDoubleTapTimeout()) {
-                mEditor.mDoubleTap = true;
-                mFirstTouch = false;
-            } else {
-                mEditor.mDoubleTap = false;
-                mFirstTouch = true;
-            }
-        }
-
-        if (action == MotionEvent.ACTION_UP) {
-            mLastTouchUpTime = SystemClock.uptimeMillis();
-        }
-
         if (mEditor != null) {
             mEditor.onTouchEvent(event);
 
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index 6e56513..acbf5eb 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -1368,11 +1368,6 @@
     }
 
     @Override
-    public int findDependentLayoutAxes(View child, int axisFilter) {
-        return findDependentLayoutAxesHelper(child, axisFilter, LayoutParams.class);
-    }
-
-    @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         int width = 0;
         int height = 0;
diff --git a/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java b/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
index e607a3f..85cc841 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
@@ -175,7 +175,7 @@
         }
 
         private final TreeMap<InputMethodInfo, List<InputMethodSubtype>> mSortedImmis =
-                new TreeMap<InputMethodInfo, List<InputMethodSubtype>>(
+                new TreeMap<>(
                         new Comparator<InputMethodInfo>() {
                             @Override
                             public int compare(InputMethodInfo imi1, InputMethodInfo imi2) {
@@ -192,14 +192,9 @@
                             }
                         });
 
-        public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeList() {
-            return getSortedInputMethodAndSubtypeList(true, false, false);
-        }
-
         public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeList(
-                boolean showSubtypes, boolean includeAuxiliarySubtypes, boolean isScreenLocked) {
-            final ArrayList<ImeSubtypeListItem> imList =
-                    new ArrayList<ImeSubtypeListItem>();
+                boolean includeAuxiliarySubtypes, boolean isScreenLocked) {
+            final ArrayList<ImeSubtypeListItem> imList = new ArrayList<>();
             final HashMap<InputMethodInfo, List<InputMethodSubtype>> immis =
                     mSettings.getExplicitlyOrImplicitlyEnabledInputMethodsAndSubtypeListLocked(
                             mContext);
@@ -219,12 +214,12 @@
                     continue;
                 }
                 List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypeList = immis.get(imi);
-                HashSet<String> enabledSubtypeSet = new HashSet<String>();
+                HashSet<String> enabledSubtypeSet = new HashSet<>();
                 for (InputMethodSubtype subtype : explicitlyOrImplicitlyEnabledSubtypeList) {
                     enabledSubtypeSet.add(String.valueOf(subtype.hashCode()));
                 }
                 final CharSequence imeLabel = imi.loadLabel(mPm);
-                if (showSubtypes && enabledSubtypeSet.size() > 0) {
+                if (enabledSubtypeSet.size() > 0) {
                     final int subtypeCount = imi.getSubtypeCount();
                     if (DEBUG) {
                         Slog.v(TAG, "Add subtypes: " + subtypeCount + ", " + imi.getId());
@@ -532,7 +527,8 @@
     public void resetCircularListLocked(Context context) {
         mSubtypeList = new InputMethodAndSubtypeList(context, mSettings);
         mController = ControllerImpl.createFrom(mController,
-                mSubtypeList.getSortedInputMethodAndSubtypeList());
+                mSubtypeList.getSortedInputMethodAndSubtypeList(
+                        false /* includeAuxiliarySubtypes */, false /* isScreenLocked */));
     }
 
     public ImeSubtypeListItem getNextInputMethodLocked(boolean onlyCurrentIme, InputMethodInfo imi,
@@ -546,10 +542,10 @@
         return mController.getNextInputMethod(onlyCurrentIme, imi, subtype);
     }
 
-    public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeListLocked(boolean showSubtypes,
+    public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeListLocked(
             boolean includingAuxiliarySubtypes, boolean isScreenLocked) {
         return mSubtypeList.getSortedInputMethodAndSubtypeList(
-                showSubtypes, includingAuxiliarySubtypes, isScreenLocked);
+                includingAuxiliarySubtypes, isScreenLocked);
     }
 
     public void dump(final Printer pw) {
diff --git a/core/java/com/android/internal/logging/MetricsConstants.java b/core/java/com/android/internal/logging/MetricsConstants.java
index 6cc8ba9..37bf71c 100644
--- a/core/java/com/android/internal/logging/MetricsConstants.java
+++ b/core/java/com/android/internal/logging/MetricsConstants.java
@@ -280,6 +280,8 @@
     public static final int ACTION_FINGERPRINT_RENAME = 254;
     public static final int ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE = 255;
     public static final int ACTION_WIGGLE_CAMERA_GESTURE = 256;
+    public static final int QS_WORKMODE = 257;
+    public static final int BACKGROUND_CHECK_SUMMARY = 258;
 
     // These constants must match those in the analytic pipeline, do not edit.
     // Add temporary values to the top of MetricsLogger instead.
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 4a969b2..cc815c4 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -7732,26 +7732,35 @@
                 }
 
                 final Uid u = getUidStatsLocked(mapUid(entry.uid));
-                u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
-                        entry.rxPackets);
-                u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
-                        entry.txPackets);
-                rxPackets.put(u.getUid(), entry.rxPackets);
-                txPackets.put(u.getUid(), entry.txPackets);
+                if (entry.rxBytes != 0) {
+                    u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
+                            entry.rxPackets);
+                    mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
+                            entry.rxBytes);
+                    mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
+                            entry.rxPackets);
 
-                // Sum the total number of packets so that the Rx Power and Tx Power can
-                // be evenly distributed amongst the apps.
-                totalRxPackets += entry.rxPackets;
-                totalTxPackets += entry.txPackets;
+                    rxPackets.put(u.getUid(), entry.rxPackets);
 
-                mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
-                        entry.rxBytes);
-                mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
-                        entry.txBytes);
-                mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
-                        entry.rxPackets);
-                mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
-                        entry.txPackets);
+                    // Sum the total number of packets so that the Rx Power can
+                    // be evenly distributed amongst the apps.
+                    totalRxPackets += entry.rxPackets;
+                }
+
+                if (entry.txBytes != 0) {
+                    u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
+                            entry.txPackets);
+                    mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
+                            entry.txBytes);
+                    mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
+                            entry.txPackets);
+
+                    txPackets.put(u.getUid(), entry.txPackets);
+
+                    // Sum the total number of packets so that the Tx Power can
+                    // be evenly distributed amongst the apps.
+                    totalTxPackets += entry.txPackets;
+                }
             }
         }
 
diff --git a/core/java/com/android/internal/policy/BackdropFrameRenderer.java b/core/java/com/android/internal/policy/BackdropFrameRenderer.java
index 75ca639..1b44ff3 100644
--- a/core/java/com/android/internal/policy/BackdropFrameRenderer.java
+++ b/core/java/com/android/internal/policy/BackdropFrameRenderer.java
@@ -63,17 +63,18 @@
     private boolean mReportNextDraw;
 
     private Drawable mCaptionBackgroundDrawable;
+    private Drawable mUserCaptionBackgroundDrawable;
     private Drawable mResizingBackgroundDrawable;
     private ColorDrawable mStatusBarColor;
 
     public BackdropFrameRenderer(DecorView decorView, ThreadedRenderer renderer, Rect initialBounds,
             Drawable resizingBackgroundDrawable, Drawable captionBackgroundDrawable,
-            int statusBarColor) {
+            Drawable userCaptionBackgroundDrawable, int statusBarColor) {
         setName("ResizeFrame");
 
         mRenderer = renderer;
         onResourcesLoaded(decorView, resizingBackgroundDrawable, captionBackgroundDrawable,
-                statusBarColor);
+                userCaptionBackgroundDrawable, statusBarColor);
 
         // Create a render node for the content and frame backdrop
         // which can be resized independently from the content.
@@ -92,10 +93,12 @@
     }
 
     void onResourcesLoaded(DecorView decorView, Drawable resizingBackgroundDrawable,
-            Drawable captionBackgroundDrawableDrawable, int statusBarColor) {
+            Drawable captionBackgroundDrawableDrawable, Drawable userCaptionBackgroundDrawable,
+            int statusBarColor) {
         mDecorView = decorView;
         mResizingBackgroundDrawable = resizingBackgroundDrawable;
         mCaptionBackgroundDrawable = captionBackgroundDrawableDrawable;
+        mUserCaptionBackgroundDrawable = userCaptionBackgroundDrawable;
         if (statusBarColor != 0) {
             mStatusBarColor = new ColorDrawable(statusBarColor);
             addSystemBarNodeIfNeeded();
@@ -281,8 +284,10 @@
 
         // Draw the caption and content backdrops in to our render node.
         DisplayListCanvas canvas = mFrameAndBackdropNode.start(width, height);
-        mCaptionBackgroundDrawable.setBounds(0, 0, left + width, top + mLastCaptionHeight);
-        mCaptionBackgroundDrawable.draw(canvas);
+        final Drawable drawable = mUserCaptionBackgroundDrawable != null
+                ? mUserCaptionBackgroundDrawable : mCaptionBackgroundDrawable;
+        drawable.setBounds(0, 0, left + width, top + mLastCaptionHeight);
+        drawable.draw(canvas);
 
         // The backdrop: clear everything with the background. Clipping is done elsewhere.
         mResizingBackgroundDrawable.setBounds(0, mLastCaptionHeight, left + width, top + height);
@@ -324,4 +329,8 @@
             mChoreographer.postFrameCallback(this);
         }
     }
+
+    void setUserCaptionBackgroundDrawable(Drawable userCaptionBackgroundDrawable) {
+        mUserCaptionBackgroundDrawable = userCaptionBackgroundDrawable;
+    }
 }
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 9107b1f..e405564 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -74,6 +74,8 @@
 import static android.view.View.MeasureSpec.getMode;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+import static android.view.Window.DECOR_CAPTION_SHADE_DARK;
+import static android.view.Window.DECOR_CAPTION_SHADE_LIGHT;
 import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
 import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
@@ -184,9 +186,10 @@
 
     private boolean mWindowResizeCallbacksAdded = false;
 
-    BackdropFrameRenderer mBackdropFrameRenderer = null;
+    private BackdropFrameRenderer mBackdropFrameRenderer = null;
     private Drawable mResizingBackgroundDrawable;
     private Drawable mCaptionBackgroundDrawable;
+    private Drawable mUserCaptionBackgroundDrawable;
 
     DecorView(Context context, int featureId, PhoneWindow window) {
         super(context);
@@ -1158,6 +1161,17 @@
                 lp.height = insets.getSystemWindowInsetBottom();
                 mNavigationGuard.setLayoutParams(lp);
             }
+            updateNavigationGuardColor();
+        }
+    }
+
+    void updateNavigationGuardColor() {
+        if (mNavigationGuard != null) {
+            // Make navigation bar guard invisible if the transparent color is specified.
+            // Only TRANSPARENT is sufficient for hiding the navigation bar if the no software
+            // keyboard is shown by IMS.
+            mNavigationGuard.setVisibility(mWindow.getNavigationBarColor() == Color.TRANSPARENT ?
+                    View.INVISIBLE : View.VISIBLE);
         }
     }
 
@@ -1569,18 +1583,20 @@
         initializeElevation();
     }
 
-    View onResourcesLoaded(LayoutInflater inflater, int layoutResource) {
+    void onResourcesLoaded(LayoutInflater inflater, int layoutResource) {
         mStackId = getStackId();
 
         mResizingBackgroundDrawable = getResizingBackgroundDrawable(
                 mWindow.mBackgroundResource, mWindow.mBackgroundFallbackResource);
-        mCaptionBackgroundDrawable =
-                getContext().getDrawable(R.drawable.decor_caption_title_focused);
+        if (mCaptionBackgroundDrawable == null) {
+            mCaptionBackgroundDrawable = getContext().getDrawable(
+                    R.drawable.decor_caption_title_focused);
+        }
 
         if (mBackdropFrameRenderer != null) {
             mBackdropFrameRenderer.onResourcesLoaded(
                     this, mResizingBackgroundDrawable, mCaptionBackgroundDrawable,
-                    getCurrentColor(mStatusColorViewState));
+                    mUserCaptionBackgroundDrawable, getCurrentColor(mStatusColorViewState));
         }
 
         mDecorCaptionView = createDecorCaptionView(inflater);
@@ -1597,17 +1613,16 @@
         }
         mContentRoot = (ViewGroup) root;
         initializeElevation();
-        return root;
     }
 
     // Free floating overlapping windows require a caption.
     private DecorCaptionView createDecorCaptionView(LayoutInflater inflater) {
-        DecorCaptionView DecorCaptionView = null;
-        for (int i = getChildCount() - 1; i >= 0 && DecorCaptionView == null; i--) {
+        DecorCaptionView decorCaptionView = null;
+        for (int i = getChildCount() - 1; i >= 0 && decorCaptionView == null; i--) {
             View view = getChildAt(i);
             if (view instanceof DecorCaptionView) {
                 // The decor was most likely saved from a relaunch - so reuse it.
-                DecorCaptionView = (DecorCaptionView) view;
+                decorCaptionView = (DecorCaptionView) view;
                 removeViewAt(i);
             }
         }
@@ -1619,27 +1634,72 @@
                 && ActivityManager.StackId.hasWindowDecor(mStackId)) {
             // Dependent on the brightness of the used title we either use the
             // dark or the light button frame.
-            if (DecorCaptionView == null) {
-                Context context = getContext();
-                TypedValue value = new TypedValue();
-                context.getTheme().resolveAttribute(R.attr.colorPrimary, value, true);
-                inflater = inflater.from(context);
-                if (Color.luminance(value.data) < 0.5) {
-                    DecorCaptionView = (DecorCaptionView) inflater.inflate(
-                            R.layout.decor_caption_dark, null);
-                } else {
-                    DecorCaptionView = (DecorCaptionView) inflater.inflate(
-                            R.layout.decor_caption_light, null);
-                }
+            if (decorCaptionView == null) {
+                decorCaptionView = inflateDecorCaptionView(inflater);
             }
-            DecorCaptionView.setPhoneWindow(mWindow, true /*showDecor*/);
+            decorCaptionView.setPhoneWindow(mWindow, true /*showDecor*/);
         } else {
-            DecorCaptionView = null;
+            decorCaptionView = null;
         }
 
         // Tell the decor if it has a visible caption.
-        enableCaption(DecorCaptionView != null);
-        return DecorCaptionView;
+        enableCaption(decorCaptionView != null);
+        return decorCaptionView;
+    }
+
+    private DecorCaptionView inflateDecorCaptionView(LayoutInflater inflater) {
+        final Context context = getContext();
+        // We make a copy of the inflater, so it has the right context associated with it.
+        inflater = inflater.from(context);
+        final DecorCaptionView view = (DecorCaptionView) inflater.inflate(R.layout.decor_caption,
+                null);
+        setDecorCaptionShade(context, view);
+        return view;
+    }
+
+    private void setDecorCaptionShade(Context context, DecorCaptionView view) {
+        final int shade = mWindow.getDecorCaptionShade();
+        switch (shade) {
+            case DECOR_CAPTION_SHADE_LIGHT:
+                setLightDecorCaptionShade(view);
+                break;
+            case DECOR_CAPTION_SHADE_DARK:
+                setDarkDecorCaptionShade(view);
+                break;
+            default: {
+                TypedValue value = new TypedValue();
+                context.getTheme().resolveAttribute(R.attr.colorPrimary, value, true);
+                // We invert the shade depending on brightness of the theme. Dark shade for light
+                // theme and vice versa. Thanks to this the buttons should be visible on the
+                // background.
+                if (Color.luminance(value.data) < 0.5) {
+                    setLightDecorCaptionShade(view);
+                } else {
+                    setDarkDecorCaptionShade(view);
+                }
+                break;
+            }
+        }
+    }
+
+    void updateDecorCaptionShade() {
+        if (mDecorCaptionView != null) {
+            setDecorCaptionShade(getContext(), mDecorCaptionView);
+        }
+    }
+
+    private void setLightDecorCaptionShade(DecorCaptionView view) {
+        view.findViewById(R.id.maximize_window).setBackgroundResource(
+                R.drawable.decor_maximize_button_light);
+        view.findViewById(R.id.close_window).setBackgroundResource(
+                R.drawable.decor_close_button_light);
+    }
+
+    private void setDarkDecorCaptionShade(DecorCaptionView view) {
+        view.findViewById(R.id.maximize_window).setBackgroundResource(
+                R.drawable.decor_maximize_button_dark);
+        view.findViewById(R.id.close_window).setBackgroundResource(
+                R.drawable.decor_close_button_dark);
     }
 
     /**
@@ -1724,11 +1784,11 @@
         if (mBackdropFrameRenderer != null) {
             return;
         }
-        final ThreadedRenderer renderer = (ThreadedRenderer) getHardwareRenderer();
+        final ThreadedRenderer renderer = getHardwareRenderer();
         if (renderer != null) {
             mBackdropFrameRenderer = new BackdropFrameRenderer(this, renderer,
                     initialBounds, mResizingBackgroundDrawable, mCaptionBackgroundDrawable,
-                    getCurrentColor(mStatusColorViewState));
+                    mUserCaptionBackgroundDrawable, getCurrentColor(mStatusColorViewState));
 
             // Get rid of the shadow while we are resizing. Shadow drawing takes considerable time.
             // If we want to get the shadow shown while resizing, we would need to elevate a new
@@ -1838,6 +1898,16 @@
                 getResources().getDisplayMetrics());
     }
 
+    /**
+     * Provide an override of the caption background drawable.
+     */
+    void setUserCaptionBackgroundDrawable(Drawable drawable) {
+        mUserCaptionBackgroundDrawable = drawable;
+        if (mBackdropFrameRenderer != null) {
+            mBackdropFrameRenderer.setUserCaptionBackgroundDrawable(drawable);
+        }
+    }
+
     private static class ColorViewState {
         View view = null;
         int targetVisibility = View.INVISIBLE;
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 57d2244..86bd782 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -94,7 +94,6 @@
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 import android.widget.FrameLayout;
-import android.widget.LinearLayout;
 import android.widget.ImageView;
 import android.widget.ProgressBar;
 import android.widget.TextView;
@@ -273,6 +272,8 @@
     private boolean mIsStartingWindow;
     private int mTheme = -1;
 
+    private int mDecorCaptionShade = DECOR_CAPTION_SHADE_AUTO;
+
     static class WindowManagerHolder {
         static final IWindowManager sWindowManager = IWindowManager.Stub.asInterface(
                 ServiceManager.getService("window"));
@@ -423,30 +424,6 @@
     }
 
     @Override
-    public void setDecorView(int layoutResID) {
-        View v = mLayoutInflater.inflate(layoutResID, null);
-        setDecorView(v);
-    }
-
-    @Override
-    public void setDecorView(View view) {
-        if (mContentParent == null) {
-            installDecor();
-        }
-
-        LinearLayout clientDecorPlaceholder =
-                (LinearLayout) findViewById(R.id.client_decor_placeholder);
-
-        if (clientDecorPlaceholder != null) {
-            clientDecorPlaceholder.removeAllViews();
-
-            if (view != null) {
-                clientDecorPlaceholder.addView(view);
-            }
-        }
-    }
-
-    @Override
     public void addContentView(View view, ViewGroup.LayoutParams params) {
         if (mContentParent == null) {
             installDecor();
@@ -2551,7 +2528,7 @@
         }
 
         mDecor.startChanging();
-        final View in = mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);
+        mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);
 
         ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
         if (contentParent == null) {
@@ -3726,6 +3703,7 @@
         mForcedNavigationBarColor = true;
         if (mDecor != null) {
             mDecor.updateColorViews(null, false /* animate */);
+            mDecor.updateNavigationGuardColor();
         }
     }
 
@@ -3743,4 +3721,21 @@
             }
         }
     }
+
+    @Override
+    public void setResizingCaptionDrawable(Drawable drawable) {
+        mDecor.setUserCaptionBackgroundDrawable(drawable);
+    }
+
+    @Override
+    public void setDecorCaptionShade(int decorCaptionShade) {
+        mDecorCaptionShade = decorCaptionShade;
+        if (mDecor != null) {
+            mDecor.updateDecorCaptionShade();
+        }
+    }
+
+    int getDecorCaptionShade() {
+        return mDecorCaptionShade;
+    }
 }
diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java
index 6816646..554d367 100644
--- a/core/java/com/android/internal/util/StateMachine.java
+++ b/core/java/com/android/internal/util/StateMachine.java
@@ -1879,6 +1879,33 @@
     }
 
     /**
+     * Check if there are any pending messages with code 'what' in deferred messages queue.
+     */
+    protected final boolean hasDeferredMessages(int what) {
+        SmHandler smh = mSmHandler;
+        if (smh == null) return false;
+
+        Iterator<Message> iterator = smh.mDeferredMessages.iterator();
+        while (iterator.hasNext()) {
+            Message msg = iterator.next();
+            if (msg.what == what) return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Check if there are any pending posts of messages with code 'what' in
+     * the message queue. This does NOT check messages in deferred message queue.
+     */
+    protected final boolean hasMessages(int what) {
+        SmHandler smh = mSmHandler;
+        if (smh == null) return false;
+
+        return smh.hasMessages(what);
+    }
+
+    /**
      * Validate that the message was sent by
      * {@link StateMachine#quit} or {@link StateMachine#quitNow}.
      * */
diff --git a/core/java/com/android/internal/util/WakeupMessage.java b/core/java/com/android/internal/util/WakeupMessage.java
new file mode 100644
index 0000000..77859b8
--- /dev/null
+++ b/core/java/com/android/internal/util/WakeupMessage.java
@@ -0,0 +1,79 @@
+/*
+ * 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.internal.util;
+
+import android.app.AlarmManager;
+import android.content.Context;
+import android.os.Handler;
+import android.os.Message;
+
+ /**
+ * An AlarmListener that sends the specified message to a Handler and keeps the system awake until
+ * the message is processed.
+ *
+ * This is useful when using the AlarmManager direct callback interface to wake up the system and
+ * request that an object whose API consists of messages (such as a StateMachine) perform some
+ * action.
+ *
+ * In this situation, using AlarmManager.onAlarmListener by itself will wake up the system to send
+ * the message, but does not guarantee that the system will be awake until the target object has
+ * processed it. This is because as soon as the onAlarmListener sends the message and returns, the
+ * AlarmManager releases its wakelock and the system is free to go to sleep again.
+ *
+ */
+public class WakeupMessage implements AlarmManager.OnAlarmListener {
+    private static AlarmManager sAlarmManager;
+    private final Handler mHandler;
+    private final String mCmdName;
+    private final int mCmd, mArg1, mArg2;
+
+    public WakeupMessage(Context context, Handler handler,
+            String cmdName, int cmd, int arg1, int arg2) {
+        if (sAlarmManager == null) {
+            sAlarmManager = context.getSystemService(AlarmManager.class);
+        }
+        mHandler = handler;
+        mCmdName = cmdName;
+        mCmd = cmd;
+        mArg1 = arg1;
+        mArg2 = arg2;
+    }
+
+    public WakeupMessage(Context context, Handler handler, String cmdName, int cmd, int arg1) {
+        this(context, handler, cmdName, cmd, arg1, 0);
+    }
+
+    public WakeupMessage(Context context, Handler handler, String cmdName, int cmd) {
+        this(context, handler, cmdName, cmd, 0, 0);
+    }
+
+    public void schedule(long when) {
+        sAlarmManager.setExact(
+                AlarmManager.ELAPSED_REALTIME_WAKEUP, when, mCmdName, this, mHandler);
+    }
+
+    public void cancel() {
+        sAlarmManager.cancel(this);
+    }
+
+    @Override
+    public void onAlarm() {
+        Message msg = mHandler.obtainMessage(mCmd, mArg1, mArg2);
+        mHandler.handleMessage(msg);
+        msg.recycle();
+    }
+}
diff --git a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
index 3e65320..c3a7460 100644
--- a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
+++ b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
@@ -360,11 +360,6 @@
     }
 
     @Override
-    public int findDependentLayoutAxes(View child, int axisFilter) {
-        return findDependentLayoutAxesHelper(child, axisFilter, LayoutParams.class);
-    }
-
-    @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         pullChildren();
 
diff --git a/core/java/com/android/internal/widget/DecorCaptionView.java b/core/java/com/android/internal/widget/DecorCaptionView.java
index d747686..c3fe9e7 100644
--- a/core/java/com/android/internal/widget/DecorCaptionView.java
+++ b/core/java/com/android/internal/widget/DecorCaptionView.java
@@ -319,6 +319,10 @@
                         captionHeight + mContent.getMeasuredHeight());
             }
         }
+
+        // This assumes that the caption bar is at the top.
+        mOwner.notifyRestrictedCaptionAreaCallback(mMaximize.getLeft(), mMaximize.getTop(),
+                mClose.getRight(), mClose.getBottom());
     }
     /**
      * Determine if the workspace is entirely covered by the window.
diff --git a/core/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp
index dac6d96..ab0df55 100644
--- a/core/jni/android/graphics/FontFamily.cpp
+++ b/core/jni/android/graphics/FontFamily.cpp
@@ -56,10 +56,11 @@
     return result;
 }
 
-static jboolean FontFamily_addFont(JNIEnv* env, jobject clazz, jlong familyPtr, jstring path) {
+static jboolean FontFamily_addFont(JNIEnv* env, jobject clazz, jlong familyPtr, jstring path,
+        jint ttcIndex) {
     NPE_CHECK_RETURN_ZERO(env, path);
     ScopedUtfChars str(env, path);
-    SkTypeface* face = SkTypeface::CreateFromFile(str.c_str());
+    SkTypeface* face = SkTypeface::CreateFromFile(str.c_str(), ttcIndex);
     if (face == NULL) {
         ALOGE("addFont failed to create font %s", str.c_str());
         return false;
@@ -69,10 +70,10 @@
 }
 
 static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong familyPtr,
-        jstring path, jint weight, jboolean isItalic) {
+        jstring path, jint ttcIndex, jint weight, jboolean isItalic) {
     NPE_CHECK_RETURN_ZERO(env, path);
     ScopedUtfChars str(env, path);
-    SkTypeface* face = SkTypeface::CreateFromFile(str.c_str());
+    SkTypeface* face = SkTypeface::CreateFromFile(str.c_str(), ttcIndex);
     if (face == NULL) {
         ALOGE("addFont failed to create font %s", str.c_str());
         return false;
@@ -127,8 +128,8 @@
 static const JNINativeMethod gFontFamilyMethods[] = {
     { "nCreateFamily",         "(Ljava/lang/String;I)J", (void*)FontFamily_create },
     { "nUnrefFamily",          "(J)V", (void*)FontFamily_unref },
-    { "nAddFont",              "(JLjava/lang/String;)Z", (void*)FontFamily_addFont },
-    { "nAddFontWeightStyle",   "(JLjava/lang/String;IZ)Z", (void*)FontFamily_addFontWeightStyle },
+    { "nAddFont",              "(JLjava/lang/String;I)Z", (void*)FontFamily_addFont },
+    { "nAddFontWeightStyle",   "(JLjava/lang/String;IIZ)Z", (void*)FontFamily_addFontWeightStyle },
     { "nAddFontFromAsset",     "(JLandroid/content/res/AssetManager;Ljava/lang/String;)Z",
                                            (void*)FontFamily_addFontFromAsset },
 };
diff --git a/core/jni/android/graphics/MinikinUtils.cpp b/core/jni/android/graphics/MinikinUtils.cpp
index 9b774b3..0597d3f 100644
--- a/core/jni/android/graphics/MinikinUtils.cpp
+++ b/core/jni/android/graphics/MinikinUtils.cpp
@@ -33,11 +33,10 @@
     FontStyle resolved = resolvedFace->fStyle;
 
     /* Prepare minikin FontStyle */
-    const std::string& langs = paint->getTextLocales();
-    FontLanguages minikinLangs(langs.c_str(), langs.size());
     FontVariant minikinVariant = (paint->getFontVariant() == VARIANT_ELEGANT) ? VARIANT_ELEGANT
             : VARIANT_COMPACT;
-    FontStyle minikinStyle(minikinLangs, minikinVariant, resolved.getWeight(), resolved.getItalic());
+    const uint32_t langListId = paint->getMinikinLangListId();
+    FontStyle minikinStyle(langListId, minikinVariant, resolved.getWeight(), resolved.getItalic());
 
     /* Prepare minikin Paint */
     // Note: it would be nice to handle fractional size values (it would improve smooth zoom
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 9c11dd1..654d148 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -71,13 +71,6 @@
     paint->setTextEncoding(Paint::kGlyphID_TextEncoding);
 }
 
-struct LocalesCacheEntry {
-    std::string javaLocales;
-    std::string languageTags;
-};
-
-static thread_local LocalesCacheEntry sSingleEntryLocalesCache;
-
 namespace PaintGlue {
     enum MoveOpt {
         AFTER, AT_OR_AFTER, BEFORE, AT_OR_BEFORE, AT
@@ -402,15 +395,20 @@
         }
     }
 
-    static void setTextLocales(JNIEnv* env, jobject clazz, jlong objHandle, jstring locales) {
+    static jint setTextLocales(JNIEnv* env, jobject clazz, jlong objHandle, jstring locales) {
         Paint* obj = reinterpret_cast<Paint*>(objHandle);
         ScopedUtfChars localesChars(env, locales);
-        if (sSingleEntryLocalesCache.javaLocales != localesChars.c_str()) {
-            sSingleEntryLocalesCache.javaLocales = localesChars.c_str();
-            toLanguageTags(&sSingleEntryLocalesCache.languageTags, localesChars.c_str());
-        }
+        std::string buf;
+        toLanguageTags(&buf, localesChars.c_str());
+        jint minikinLangListId = FontStyle::registerLanguageList(buf);
+        obj->setMinikinLangListId(minikinLangListId);
+        return minikinLangListId;
+    }
 
-        obj->setTextLocales(sSingleEntryLocalesCache.languageTags);
+    static void setTextLocalesByMinikinLangListId(JNIEnv* env, jobject clazz, jlong objHandle,
+            jint minikinLangListId) {
+        Paint* obj = reinterpret_cast<Paint*>(objHandle);
+        obj->setMinikinLangListId(minikinLangListId);
     }
 
     static jboolean isElegantTextHeight(JNIEnv* env, jobject, jlong paintHandle) {
@@ -991,7 +989,9 @@
     {"nSetRasterizer","!(JJ)J", (void*) PaintGlue::setRasterizer},
     {"nGetTextAlign","!(J)I", (void*) PaintGlue::getTextAlign},
     {"nSetTextAlign","!(JI)V", (void*) PaintGlue::setTextAlign},
-    {"nSetTextLocales","!(JLjava/lang/String;)V", (void*) PaintGlue::setTextLocales},
+    {"nSetTextLocales","!(JLjava/lang/String;)I", (void*) PaintGlue::setTextLocales},
+    {"nSetTextLocalesByMinikinLangListId","!(JI)V",
+            (void*) PaintGlue::setTextLocalesByMinikinLangListId},
     {"nIsElegantTextHeight","!(J)Z", (void*) PaintGlue::isElegantTextHeight},
     {"nSetElegantTextHeight","!(JZ)V", (void*) PaintGlue::setElegantTextHeight},
     {"nGetTextSize","!(J)F", (void*) PaintGlue::getTextSize},
diff --git a/core/jni/android/graphics/Paint.h b/core/jni/android/graphics/Paint.h
index 7a34bc2..cb6e622 100644
--- a/core/jni/android/graphics/Paint.h
+++ b/core/jni/android/graphics/Paint.h
@@ -53,12 +53,12 @@
         return mFontFeatureSettings;
     }
 
-    void setTextLocales(const std::string &textLocales) {
-        mTextLocales = textLocales;
+    void setMinikinLangListId(uint32_t minikinLangListId) {
+        mMinikinLangListId = minikinLangListId;
     }
 
-    const std::string& getTextLocales() const {
-        return mTextLocales;
+    uint32_t getMinikinLangListId() const {
+        return mMinikinLangListId;
     }
 
     void setFontVariant(FontVariant variant) {
@@ -80,7 +80,7 @@
 private:
     float mLetterSpacing = 0;
     std::string mFontFeatureSettings;
-    std::string mTextLocales;
+    uint32_t mMinikinLangListId;
     FontVariant mFontVariant;
     uint32_t mHyphenEdit = 0;
 };
diff --git a/core/jni/android/graphics/PaintImpl.cpp b/core/jni/android/graphics/PaintImpl.cpp
index d5a0972..bd513ae 100644
--- a/core/jni/android/graphics/PaintImpl.cpp
+++ b/core/jni/android/graphics/PaintImpl.cpp
@@ -22,13 +22,14 @@
 
 namespace android {
 
-Paint::Paint() : SkPaint(),
-        mLetterSpacing(0), mFontFeatureSettings(), mTextLocales(), mFontVariant(VARIANT_DEFAULT) {
+Paint::Paint() :
+        SkPaint(), mLetterSpacing(0), mFontFeatureSettings(), mMinikinLangListId(0),
+        mFontVariant(VARIANT_DEFAULT) {
 }
 
 Paint::Paint(const Paint& paint) : SkPaint(paint),
         mLetterSpacing(paint.mLetterSpacing), mFontFeatureSettings(paint.mFontFeatureSettings),
-        mTextLocales(paint.mTextLocales), mFontVariant(paint.mFontVariant),
+        mMinikinLangListId(paint.mMinikinLangListId), mFontVariant(paint.mFontVariant),
         mHyphenEdit(paint.mHyphenEdit) {
 }
 
@@ -39,7 +40,7 @@
     SkPaint::operator=(other);
     mLetterSpacing = other.mLetterSpacing;
     mFontFeatureSettings = other.mFontFeatureSettings;
-    mTextLocales = other.mTextLocales;
+    mMinikinLangListId = other.mMinikinLangListId;
     mFontVariant = other.mFontVariant;
     mHyphenEdit = other.mHyphenEdit;
     return *this;
@@ -49,7 +50,7 @@
     return static_cast<const SkPaint&>(a) == static_cast<const SkPaint&>(b)
             && a.mLetterSpacing == b.mLetterSpacing
             && a.mFontFeatureSettings == b.mFontFeatureSettings
-            && a.mTextLocales == b.mTextLocales
+            && a.mMinikinLangListId == b.mMinikinLangListId
             && a.mFontVariant == b.mFontVariant
             && a.mHyphenEdit == b.mHyphenEdit;
 }
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 1ee7ea8..2488111 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -595,6 +595,36 @@
     MEMINFO_COUNT
 };
 
+static long long get_zram_mem_used()
+{
+#define ZRAM_SYSFS "/sys/block/zram0/"
+    FILE *f = fopen(ZRAM_SYSFS "mm_stat", "r");
+    if (f) {
+        long long mem_used_total = 0;
+
+        int matched = fscanf(f, "%*d %*d %lld %*d %*d %*d %*d", &mem_used_total);
+        if (matched != 1)
+            ALOGW("failed to parse " ZRAM_SYSFS "mm_stat");
+
+        fclose(f);
+        return mem_used_total;
+    }
+
+    f = fopen(ZRAM_SYSFS "mem_used_total", "r");
+    if (f) {
+        long long mem_used_total = 0;
+
+        int matched = fscanf(f, "%lld", &mem_used_total);
+        if (matched != 1)
+            ALOGW("failed to parse " ZRAM_SYSFS "mem_used_total");
+
+        fclose(f);
+        return mem_used_total;
+    }
+
+    return 0;
+}
+
 static void android_os_Debug_getMemInfo(JNIEnv *env, jobject clazz, jlongArray out)
 {
     char buffer[1024];
@@ -680,15 +710,7 @@
         if (*p) p++;
     }
 
-    fd = open("/sys/block/zram0/mem_used_total", O_RDONLY);
-    if (fd >= 0) {
-        len = read(fd, buffer, sizeof(buffer)-1);
-        close(fd);
-        if (len > 0) {
-            buffer[len] = 0;
-            mem[MEMINFO_ZRAM_TOTAL] = atoll(buffer)/1024;
-        }
-    }
+    mem[MEMINFO_ZRAM_TOTAL] = get_zram_mem_used() / 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;
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index ff51e4e..f6e68c4 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -149,7 +149,9 @@
         case PublicFormat::DEPTH16:
             return HAL_DATASPACE_DEPTH;
         case PublicFormat::RAW_SENSOR:
+        case PublicFormat::RAW_PRIVATE:
         case PublicFormat::RAW10:
+        case PublicFormat::RAW12:
             return HAL_DATASPACE_ARBITRARY;
         case PublicFormat::YUV_420_888:
         case PublicFormat::NV21:
@@ -170,6 +172,7 @@
         case HAL_PIXEL_FORMAT_RGB_565:
         case HAL_PIXEL_FORMAT_Y8:
         case HAL_PIXEL_FORMAT_RAW10:
+        case HAL_PIXEL_FORMAT_RAW12:
         case HAL_PIXEL_FORMAT_YCbCr_420_888:
         case HAL_PIXEL_FORMAT_YV12:
             // Enums overlap in both name and value
@@ -177,6 +180,9 @@
         case HAL_PIXEL_FORMAT_RAW16:
             // Name differs, though value is the same
             return PublicFormat::RAW_SENSOR;
+        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
+            // Name differs, though value is the same
+            return PublicFormat::RAW_PRIVATE;
         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
             // Name differs, though the value is the same
             return PublicFormat::NV16;
@@ -212,7 +218,6 @@
             }
             break;
         case HAL_PIXEL_FORMAT_BGRA_8888:
-        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
             // Not defined in public API
             return PublicFormat::UNKNOWN;
 
diff --git a/core/res/Android.mk b/core/res/Android.mk
index cfc791d..a1bef83 100644
--- a/core/res/Android.mk
+++ b/core/res/Android.mk
@@ -23,6 +23,7 @@
 # Tell aapt to create "extending (non-application)" resource IDs,
 # since these resources will be used by many apps.
 LOCAL_AAPT_FLAGS := -x
+LOCAL_AAPT_FLAGS += --private-symbols com.android.internal
 
 LOCAL_MODULE_TAGS := optional
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index ee493019..1127197 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -277,6 +277,7 @@
     <protected-broadcast android:name="android.intent.action.ADVANCED_SETTINGS" />
     <protected-broadcast android:name="android.intent.action.APPLICATION_RESTRICTIONS_CHANGED" />
     <protected-broadcast android:name="android.intent.action.BUGREPORT_FINISHED" />
+    <protected-broadcast android:name="android.intent.action.BUGREPORT_STARTED" />
 
     <protected-broadcast android:name="android.intent.action.ACTION_IDLE_MAINTENANCE_START" />
     <protected-broadcast android:name="android.intent.action.ACTION_IDLE_MAINTENANCE_END" />
@@ -322,6 +323,52 @@
     <protected-broadcast android:name="android.internal.policy.action.BURN_IN_PROTECTION" />
     <protected-broadcast android:name="android.app.action.SYSTEM_UPDATE_POLICY_CHANGED" />
     <protected-broadcast android:name="android.app.action.DEVICE_OWNER_CHANGED" />
+
+    <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED" />
+    <protected-broadcast android:name="android.intent.action.AVAILABILITY_CHANGED" />
+
+    <!-- Added in N -->
+    <protected-broadcast android:name="android.intent.action.ANR" />
+    <protected-broadcast android:name="android.intent.action.CALL" />
+    <protected-broadcast android:name="android.intent.action.DROPBOX_ENTRY_ADDED" />
+    <protected-broadcast android:name="android.intent.action.INPUT_METHOD_CHANGED" />
+    <protected-broadcast android:name="android.intent.action.internal_sim_state_changed" />
+    <protected-broadcast android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
+    <protected-broadcast android:name="android.intent.action.PRECISE_CALL_STATE" />
+    <protected-broadcast android:name="android.intent.action.PRECISE_DATA_CONNECTION_STATE_CHANGED" />
+    <protected-broadcast android:name="android.intent.action.SUBSCRIPTION_PHONE_STATE" />
+    <protected-broadcast android:name="android.intent.action.USER_INFO_CHANGED" />
+    <protected-broadcast android:name="android.intent.action.USER_UNLOCKED" />
+    <protected-broadcast android:name="android.intent.action.WALLPAPER_CHANGED" />
+
+    <protected-broadcast android:name="android.app.action.DEVICE_POLICY_MANAGER_STATE_CHANGED" />
+    <protected-broadcast android:name="android.bluetooth.adapter.action.BLE_STATE_CHANGED" />
+    <protected-broadcast android:name="android.content.jobscheduler.JOB_DELAY_EXPIRED" />
+    <protected-broadcast android:name="android.content.syncmanager.SYNC_ALARM" />
+    <protected-broadcast android:name="android.media.INTERNAL_RINGER_MODE_CHANGED_ACTION" />
+    <protected-broadcast android:name="android.media.STREAM_DEVICES_CHANGED_ACTION" />
+    <protected-broadcast android:name="android.media.STREAM_MUTE_CHANGED_ACTION" />
+    <protected-broadcast android:name="android.net.sip.SIP_SERVICE_UP" />
+    <protected-broadcast android:name="android.nfc.action.ADAPTER_STATE_CHANGED" />
+    <protected-broadcast android:name="android.os.action.CHARGING" />
+    <protected-broadcast android:name="android.os.action.DISCHARGING" />
+    <protected-broadcast android:name="android.search.action.SEARCHABLES_CHANGED" />
+    <protected-broadcast android:name="android.security.STORAGE_CHANGED" />
+    <protected-broadcast android:name="android.telecom.action.PHONE_ACCOUNT_REGISTERED" />
+    <protected-broadcast android:name="android.telecom.action.PHONE_ACCOUNT_UNREGISTERED" />
+    <protected-broadcast android:name="android.telephony.action.CARRIER_CONFIG_CHANGED" />
+
+    <protected-broadcast android:name="com.android.bluetooth.btservice.action.ALARM_WAKEUP" />
+    <protected-broadcast android:name="com.android.ims.IMS_SERVICE_UP" />
+    <protected-broadcast android:name="com.android.server.action.NETWORK_STATS_POLL" />
+    <protected-broadcast android:name="com.android.server.action.NETWORK_STATS_UPDATED" />
+    <protected-broadcast android:name="com.android.server.NetworkTimeUpdateService.action.POLL" />
+    <protected-broadcast android:name="com.android.server.telecom.intent.action.CALLS_ADD_ENTRY" />
+    <protected-broadcast android:name="com.android.settings.location.MODE_CHANGING" />
+
+    <protected-broadcast android:name="ScheduleConditionProvider.EVALUATE" />
+    <protected-broadcast android:name="wifi_scan_available" />
+
     <!-- ====================================================================== -->
     <!--                          RUNTIME PERMISSIONS                           -->
     <!-- ====================================================================== -->
@@ -2731,6 +2778,12 @@
          confirmation UI for full backup/restore -->
     <uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/>
 
+
+    <!-- Allows the holder to access the ephemeral applications on the device.
+    @hide -->
+    <permission android:name="android.permission.ACCESS_EPHEMERAL_APPS"
+            android:protectionLevel="signature" />
+
     <application android:process="system"
                  android:persistent="true"
                  android:hasCode="false"
diff --git a/core/res/res/drawable/ic_arrow_drop_down.xml b/core/res/res/drawable/ic_collapse_bundle.xml
similarity index 68%
copy from core/res/res/drawable/ic_arrow_drop_down.xml
copy to core/res/res/drawable/ic_collapse_bundle.xml
index c8bb411..26c839d0 100644
--- a/core/res/res/drawable/ic_arrow_drop_down.xml
+++ b/core/res/res/drawable/ic_collapse_bundle.xml
@@ -15,11 +15,11 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="14.0dp"
-    android:height="14.0dp"
-    android:viewportWidth="24.0"
-    android:viewportHeight="24.0">
+        android:width="14.0dp"
+        android:height="14.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
     <path
-        android:pathData="M16.600000,8.600000l-4.600000,4.599999 -4.600000,-4.599999 -1.400000,1.400000 6.000000,6.000000 6.000000,-6.000000z"
-        android:fillColor="#FF000000"/>
+        android:fillColor="#FF000000"
+        android:pathData="M12.0,10.0l5.3,-5.2l-1.4,-1.4L12.0,7.2L8.2,3.4L6.8,4.8L12.0,10.0zM6.8,19.2l1.4,1.4l3.8,-3.8l3.9,3.8l1.4,-1.4L12.0,14.0L6.8,19.2z"/>
 </vector>
diff --git a/core/res/res/drawable/ic_arrow_drop_down.xml b/core/res/res/drawable/ic_collapse_notification.xml
similarity index 67%
copy from core/res/res/drawable/ic_arrow_drop_down.xml
copy to core/res/res/drawable/ic_collapse_notification.xml
index c8bb411..603c159 100644
--- a/core/res/res/drawable/ic_arrow_drop_down.xml
+++ b/core/res/res/drawable/ic_collapse_notification.xml
@@ -15,11 +15,14 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="14.0dp"
-    android:height="14.0dp"
-    android:viewportWidth="24.0"
-    android:viewportHeight="24.0">
+        android:width="14.0dp"
+        android:height="14.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
     <path
-        android:pathData="M16.600000,8.600000l-4.600000,4.599999 -4.600000,-4.599999 -1.400000,1.400000 6.000000,6.000000 6.000000,-6.000000z"
-        android:fillColor="#FF000000"/>
+        android:fillColor="#FF000000"
+        android:pathData="M12.0,8.0l-6.0,6.0l1.4,1.4l4.6,-4.6l4.6,4.6L18.0,14.0L12.0,8.0z"/>
+    <path
+        android:pathData="M0,0h24v24H0V0z"
+        android:fillColor="#00000000"/>
 </vector>
diff --git a/core/res/res/drawable/ic_decor_close_button_dark_focused.xml b/core/res/res/drawable/ic_decor_close_button_dark_focused.xml
index d7b167dd..0794ed3 100644
--- a/core/res/res/drawable/ic_decor_close_button_dark_focused.xml
+++ b/core/res/res/drawable/ic_decor_close_button_dark_focused.xml
@@ -23,7 +23,7 @@
            android:translateX="8.0"
            android:translateY="8.0" >
         <path
-            android:fillColor="#FFFFFFFF"
+            android:fillColor="#ff000000"
             android:pathData="M6.9,4.0l-2.9,2.9 9.1,9.1 -9.1,9.200001 2.9,2.799999 9.1,-9.1 9.1,9.1 2.9,-2.799999 -9.1,-9.200001 9.1,-9.1 -2.9,-2.9 -9.1,9.2z"/>
     </group>
 </vector>
diff --git a/core/res/res/drawable/ic_decor_close_button_dark_unfocused.xml b/core/res/res/drawable/ic_decor_close_button_dark_unfocused.xml
index e2e81b9..bd1db51 100644
--- a/core/res/res/drawable/ic_decor_close_button_dark_unfocused.xml
+++ b/core/res/res/drawable/ic_decor_close_button_dark_unfocused.xml
@@ -23,7 +23,7 @@
            android:translateX="8.0"
            android:translateY="8.0" >
         <path
-            android:fillColor="#33FFFFFF"
+            android:fillColor="#33000000"
             android:pathData="M6.9,4.0l-2.9,2.9 9.1,9.1 -9.1,9.200001 2.9,2.799999 9.1,-9.1 9.1,9.1 2.9,-2.799999 -9.1,-9.200001 9.1,-9.1 -2.9,-2.9 -9.1,9.2z"/>
     </group>
 </vector>
diff --git a/core/res/res/drawable/ic_decor_close_button_light_focused.xml b/core/res/res/drawable/ic_decor_close_button_light_focused.xml
index 0794ed3..d7b167dd 100644
--- a/core/res/res/drawable/ic_decor_close_button_light_focused.xml
+++ b/core/res/res/drawable/ic_decor_close_button_light_focused.xml
@@ -23,7 +23,7 @@
            android:translateX="8.0"
            android:translateY="8.0" >
         <path
-            android:fillColor="#ff000000"
+            android:fillColor="#FFFFFFFF"
             android:pathData="M6.9,4.0l-2.9,2.9 9.1,9.1 -9.1,9.200001 2.9,2.799999 9.1,-9.1 9.1,9.1 2.9,-2.799999 -9.1,-9.200001 9.1,-9.1 -2.9,-2.9 -9.1,9.2z"/>
     </group>
 </vector>
diff --git a/core/res/res/drawable/ic_decor_close_button_light_unfocused.xml b/core/res/res/drawable/ic_decor_close_button_light_unfocused.xml
index bd1db51..e2e81b9 100644
--- a/core/res/res/drawable/ic_decor_close_button_light_unfocused.xml
+++ b/core/res/res/drawable/ic_decor_close_button_light_unfocused.xml
@@ -23,7 +23,7 @@
            android:translateX="8.0"
            android:translateY="8.0" >
         <path
-            android:fillColor="#33000000"
+            android:fillColor="#33FFFFFF"
             android:pathData="M6.9,4.0l-2.9,2.9 9.1,9.1 -9.1,9.200001 2.9,2.799999 9.1,-9.1 9.1,9.1 2.9,-2.799999 -9.1,-9.200001 9.1,-9.1 -2.9,-2.9 -9.1,9.2z"/>
     </group>
 </vector>
diff --git a/core/res/res/drawable/ic_decor_maximize_button_dark_focused.xml b/core/res/res/drawable/ic_decor_maximize_button_dark_focused.xml
index 73d808b..c23390e 100644
--- a/core/res/res/drawable/ic_decor_maximize_button_dark_focused.xml
+++ b/core/res/res/drawable/ic_decor_maximize_button_dark_focused.xml
@@ -23,10 +23,10 @@
            android:translateX="8.0"
            android:translateY="8.0" >
         <path
-            android:fillColor="#FFFFFFFF"
+            android:fillColor="#FF000000"
             android:pathData="M2.0,4.0l0.0,16.0l28.0,0.0L30.0,4.0L2.0,4.0zM26.0,16.0L6.0,16.0L6.0,8.0l20.0,0.0L26.0,16.0z"/>
         <path
-            android:fillColor="#B2FFFFFF"
+            android:fillColor="#B2000000"
             android:pathData="M2.0,24.0l28.0,0.0l0.0,4.0l-28.0,0.0z"/>
     </group>
 </vector>
diff --git a/core/res/res/drawable/ic_decor_maximize_button_dark_unfocused.xml b/core/res/res/drawable/ic_decor_maximize_button_dark_unfocused.xml
index dc79e10..a194a39 100644
--- a/core/res/res/drawable/ic_decor_maximize_button_dark_unfocused.xml
+++ b/core/res/res/drawable/ic_decor_maximize_button_dark_unfocused.xml
@@ -23,10 +23,10 @@
            android:translateX="8.0"
            android:translateY="8.0" >
         <path
-            android:fillColor="#33FFFFFF"
+            android:fillColor="#33000000"
             android:pathData="M2.0,4.0l0.0,16.0l28.0,0.0L30.0,4.0L2.0,4.0zM26.0,16.0L6.0,16.0L6.0,8.0l20.0,0.0L26.0,16.0z"/>
         <path
-            android:fillColor="#33FFFFFF"
+            android:fillColor="#33000000"
             android:pathData="M2.0,24.0l28.0,0.0l0.0,4.0l-28.0,0.0z"/>
     </group>
 </vector>
diff --git a/core/res/res/drawable/ic_decor_maximize_button_light_focused.xml b/core/res/res/drawable/ic_decor_maximize_button_light_focused.xml
index c23390e..73d808b 100644
--- a/core/res/res/drawable/ic_decor_maximize_button_light_focused.xml
+++ b/core/res/res/drawable/ic_decor_maximize_button_light_focused.xml
@@ -23,10 +23,10 @@
            android:translateX="8.0"
            android:translateY="8.0" >
         <path
-            android:fillColor="#FF000000"
+            android:fillColor="#FFFFFFFF"
             android:pathData="M2.0,4.0l0.0,16.0l28.0,0.0L30.0,4.0L2.0,4.0zM26.0,16.0L6.0,16.0L6.0,8.0l20.0,0.0L26.0,16.0z"/>
         <path
-            android:fillColor="#B2000000"
+            android:fillColor="#B2FFFFFF"
             android:pathData="M2.0,24.0l28.0,0.0l0.0,4.0l-28.0,0.0z"/>
     </group>
 </vector>
diff --git a/core/res/res/drawable/ic_decor_maximize_button_light_unfocused.xml b/core/res/res/drawable/ic_decor_maximize_button_light_unfocused.xml
index a194a39..dc79e10 100644
--- a/core/res/res/drawable/ic_decor_maximize_button_light_unfocused.xml
+++ b/core/res/res/drawable/ic_decor_maximize_button_light_unfocused.xml
@@ -23,10 +23,10 @@
            android:translateX="8.0"
            android:translateY="8.0" >
         <path
-            android:fillColor="#33000000"
+            android:fillColor="#33FFFFFF"
             android:pathData="M2.0,4.0l0.0,16.0l28.0,0.0L30.0,4.0L2.0,4.0zM26.0,16.0L6.0,16.0L6.0,8.0l20.0,0.0L26.0,16.0z"/>
         <path
-            android:fillColor="#33000000"
+            android:fillColor="#33FFFFFF"
             android:pathData="M2.0,24.0l28.0,0.0l0.0,4.0l-28.0,0.0z"/>
     </group>
 </vector>
diff --git a/core/res/res/drawable/ic_arrow_drop_down.xml b/core/res/res/drawable/ic_expand_bundle.xml
similarity index 68%
rename from core/res/res/drawable/ic_arrow_drop_down.xml
rename to core/res/res/drawable/ic_expand_bundle.xml
index c8bb411..2cc5005 100644
--- a/core/res/res/drawable/ic_arrow_drop_down.xml
+++ b/core/res/res/drawable/ic_expand_bundle.xml
@@ -15,11 +15,11 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="14.0dp"
-    android:height="14.0dp"
-    android:viewportWidth="24.0"
-    android:viewportHeight="24.0">
+        android:width="14.0dp"
+        android:height="14.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
     <path
-        android:pathData="M16.600000,8.600000l-4.600000,4.599999 -4.600000,-4.599999 -1.400000,1.400000 6.000000,6.000000 6.000000,-6.000000z"
-        android:fillColor="#FF000000"/>
+        android:fillColor="#FF000000"
+        android:pathData="M6.8,8.6L8.2,10.0L12.0,6.2l3.9,3.8l1.4,-1.4L12.0,3.4L6.8,8.6zM12.0,20.6l5.3,-5.2L15.8,14.0L12.0,17.8L8.2,14.0l-1.4,1.4L12.0,20.6z"/>
 </vector>
diff --git a/core/res/res/drawable/ic_arrow_drop_down.xml b/core/res/res/drawable/ic_expand_notification.xml
similarity index 67%
copy from core/res/res/drawable/ic_arrow_drop_down.xml
copy to core/res/res/drawable/ic_expand_notification.xml
index c8bb411..db7d3eb 100644
--- a/core/res/res/drawable/ic_arrow_drop_down.xml
+++ b/core/res/res/drawable/ic_expand_notification.xml
@@ -15,11 +15,14 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="14.0dp"
-    android:height="14.0dp"
-    android:viewportWidth="24.0"
-    android:viewportHeight="24.0">
+        android:width="14.0dp"
+        android:height="14.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
     <path
-        android:pathData="M16.600000,8.600000l-4.600000,4.599999 -4.600000,-4.599999 -1.400000,1.400000 6.000000,6.000000 6.000000,-6.000000z"
-        android:fillColor="#FF000000"/>
+        android:fillColor="#FF000000"
+        android:pathData="M16.6,8.6L12.0,13.2L7.4,8.6L6.0,10.0l6.0,6.0l6.0,-6.0L16.6,8.6z"/>
+    <path
+        android:pathData="M0,0h24v24H0V0z"
+        android:fillColor="#00000000"/>
 </vector>
diff --git a/core/res/res/layout/decor_caption.xml b/core/res/res/layout/decor_caption.xml
new file mode 100644
index 0000000..0246736
--- /dev/null
+++ b/core/res/res/layout/decor_caption.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2015, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<com.android.internal.widget.DecorCaptionView xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:descendantFocusability="beforeDescendants" >
+    <LinearLayout
+            android:id="@+id/caption"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="end"
+            android:background="@drawable/decor_caption_title"
+            android:focusable="false"
+            android:descendantFocusability="blocksDescendants" >
+        <Button
+                android:id="@+id/maximize_window"
+                android:layout_width="32dp"
+                android:layout_height="32dp"
+                android:layout_margin="5dp"
+                android:padding="4dp"
+                android:layout_gravity="center_vertical|end"
+                android:contentDescription="@string/maximize_button_text"
+                android:background="@drawable/decor_maximize_button_dark" />
+        <Button
+                android:id="@+id/close_window"
+                android:layout_width="32dp"
+                android:layout_height="32dp"
+                android:layout_margin="5dp"
+                android:padding="4dp"
+                android:layout_gravity="center_vertical|end"
+                android:contentDescription="@string/close_button_text"
+                android:background="@drawable/decor_close_button_dark" />
+    </LinearLayout>
+</com.android.internal.widget.DecorCaptionView>
diff --git a/core/res/res/layout/decor_caption_dark.xml b/core/res/res/layout/decor_caption_dark.xml
deleted file mode 100644
index 273264d..0000000
--- a/core/res/res/layout/decor_caption_dark.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<com.android.internal.widget.DecorCaptionView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:descendantFocusability="beforeDescendants" >
-    <LinearLayout
-        android:id="@+id/caption"
-        android:layout_width="match_parent"
-        android:layout_gravity="end"
-        android:layout_height="wrap_content"
-        android:background="@drawable/decor_caption_title"
-        android:focusable="false"
-        android:descendantFocusability="blocksDescendants" >
-        <LinearLayout
-            android:id="@+id/client_decor_placeholder"
-            android:layout_width="0dp"
-            android:layout_height="match_parent"
-            android:layout_weight="1"/>
-        <Button
-            android:id="@+id/maximize_window"
-            android:layout_width="32dp"
-            android:layout_height="32dp"
-            android:layout_margin="5dp"
-            android:padding="4dp"
-            android:layout_gravity="center_vertical|end"
-            android:contentDescription="@string/maximize_button_text"
-            android:background="@drawable/decor_maximize_button_dark" />
-        <Button
-            android:id="@+id/close_window"
-            android:layout_width="32dp"
-            android:layout_height="32dp"
-            android:layout_margin="5dp"
-            android:padding="4dp"
-            android:layout_gravity="center_vertical|end"
-            android:contentDescription="@string/close_button_text"
-            android:background="@drawable/decor_close_button_dark" />
-    </LinearLayout>
-</com.android.internal.widget.DecorCaptionView>
diff --git a/core/res/res/layout/decor_caption_light.xml b/core/res/res/layout/decor_caption_light.xml
deleted file mode 100644
index fd9198e..0000000
--- a/core/res/res/layout/decor_caption_light.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<com.android.internal.widget.DecorCaptionView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:descendantFocusability="beforeDescendants" >
-    <LinearLayout
-        android:id="@+id/caption"
-        android:layout_width="match_parent"
-        android:layout_gravity="end"
-        android:layout_height="wrap_content"
-        android:background="@drawable/decor_caption_title"
-        android:focusable="false"
-        android:descendantFocusability="blocksDescendants" >
-        <LinearLayout
-            android:id="@+id/client_decor_placeholder"
-            android:layout_width="0dp"
-            android:layout_height="match_parent"
-            android:layout_weight="1"/>
-        <Button
-            android:id="@+id/maximize_window"
-            android:layout_width="32dp"
-            android:layout_height="32dp"
-            android:layout_margin="5dp"
-            android:padding="4dp"
-            android:layout_gravity="center_vertical|end"
-            android:contentDescription="@string/maximize_button_text"
-            android:background="@drawable/decor_maximize_button_light" />
-        <Button
-            android:id="@+id/close_window"
-            android:layout_width="32dp"
-            android:layout_height="32dp"
-            android:layout_margin="5dp"
-            android:padding="4dp"
-            android:layout_gravity="center_vertical|end"
-            android:contentDescription="@string/close_button_text"
-            android:background="@drawable/decor_close_button_light" />
-    </LinearLayout>
-</com.android.internal.widget.DecorCaptionView>
diff --git a/core/res/res/layout/notification_material_action.xml b/core/res/res/layout/notification_material_action.xml
index 62602d8..398f52d 100644
--- a/core/res/res/layout/notification_material_action.xml
+++ b/core/res/res/layout/notification_material_action.xml
@@ -22,7 +22,7 @@
     android:layout_height="48dp"
     android:layout_gravity="center"
     android:layout_marginStart="4dp"
-    android:textColor="@color/secondary_text_material_light"
+    android:textColor="@color/notification_default_color"
     android:singleLine="true"
     android:ellipsize="end"
     android:background="@drawable/notification_material_action_background"
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index aceae9f..e45f52b 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -125,7 +125,6 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:paddingTop="1dp"
-        android:src="@drawable/ic_arrow_drop_down"
         android:visibility="gone"
         />
 </NotificationHeaderView>
diff --git a/core/res/res/layout/notification_template_material_big_base.xml b/core/res/res/layout/notification_template_material_big_base.xml
index 8c78b8d..eb02e8b 100644
--- a/core/res/res/layout/notification_template_material_big_base.xml
+++ b/core/res/res/layout/notification_template_material_big_base.xml
@@ -55,12 +55,6 @@
         </FrameLayout>
         <include layout="@layout/notification_template_right_icon" />
     </FrameLayout>
-    <ImageView
-        android:layout_width="match_parent"
-        android:layout_height="1dp"
-        android:id="@+id/action_divider"
-        android:visibility="gone"
-        android:background="@drawable/notification_template_divider" />
     <include
         layout="@layout/notification_material_action_list"
         android:layout_width="match_parent"
diff --git a/core/res/res/layout/notification_template_material_big_picture.xml b/core/res/res/layout/notification_template_material_big_picture.xml
index 74e7775..58e3d1b 100644
--- a/core/res/res/layout/notification_template_material_big_picture.xml
+++ b/core/res/res/layout/notification_template_material_big_picture.xml
@@ -52,14 +52,6 @@
                 android:layout_marginBottom="16dp"
                 android:scaleType="centerCrop"
                 />
-        <ImageView
-                android:layout_width="match_parent"
-                android:layout_height="1dp"
-                android:layout_marginStart="-16dp"
-                android:layout_marginEnd="-16dp"
-                android:id="@+id/action_divider"
-                android:visibility="gone"
-                android:background="@drawable/notification_template_divider" />
         <include layout="@layout/notification_material_action_list" />
     </LinearLayout>
 </FrameLayout>
diff --git a/core/res/res/layout/notification_template_material_big_text.xml b/core/res/res/layout/notification_template_material_big_text.xml
index 354c0fb..9e010f2 100644
--- a/core/res/res/layout/notification_template_material_big_text.xml
+++ b/core/res/res/layout/notification_template_material_big_text.xml
@@ -62,14 +62,6 @@
                 android:contentDescription="@string/notification_work_profile_content_description"
                 />
         </LinearLayout>
-        <ImageView
-            android:layout_width="match_parent"
-            android:layout_height="1dp"
-            android:layout_marginStart="-16dp"
-            android:layout_marginEnd="-16dp"
-            android:id="@+id/action_divider"
-            android:visibility="gone"
-            android:background="@drawable/notification_template_divider" />
         <include layout="@layout/notification_material_action_list" />
     </LinearLayout>
     <include layout="@layout/notification_template_right_icon" />
diff --git a/core/res/res/layout/notification_template_material_inbox.xml b/core/res/res/layout/notification_template_material_inbox.xml
index 4f12d76..8c0abc9 100644
--- a/core/res/res/layout/notification_template_material_inbox.xml
+++ b/core/res/res/layout/notification_template_material_inbox.xml
@@ -130,14 +130,6 @@
             android:visibility="gone"
             android:layout_weight="0"
         />
-        <ImageView
-            android:layout_width="match_parent"
-            android:layout_height="1dip"
-            android:id="@+id/action_divider"
-            android:visibility="gone"
-            android:layout_marginStart="-16dp"
-            android:layout_marginEnd="-16dp"
-            android:background="@drawable/notification_template_divider" />
         <include layout="@layout/notification_material_action_list" />
     </LinearLayout>
     <include layout="@layout/notification_template_right_icon" />
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index c3f7afc..eaf82fb 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Stembystand"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Sluit nou"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Veiligmodus"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android-stelsel"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Persoonlik"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Opgedateer deur jou administrateur"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Deur jou administrateur uitgevee"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Om batterylewe te help verbeter, verminder batterybespaarder jou toestel se werkverrigting en beperk vibrasie, liggingdienste en die meeste agtergronddata. E-pos, boodskappe en ander programme wat op sinkronisering staatmaak, sal dalk nie opdateer tensy jy hulle oopmaak nie.\n\nBatterybespaarder skakel outomaties af wanneer jou toestel besig is om te laai."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Geblokkeer: Moet nooit hierdie kennisgewings wys nie"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Laag: Wys sonder klank aan die onderkant van die kennisgewinglys"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normaal: Wys hierdie kennisgewings sonder klank"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Hoog: Wys aan die bokant van die kennisgewingslys en maak \'n geluid"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Dringend: Verskyn vlugtig op die skerm en maak \'n geluid"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">%1$d minute lank (tot <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">Een minuut lank (tot <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 4de0097..03dbcae 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"የድምጽ እርዳታ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"አሁን ቆልፍ"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"የሚያስተማምን ሁነታ"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android ስርዓት"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"የግል"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"በአስተዳዳሪዎ ተዘምኗል"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"በእርስዎ አስተዳዳሪ ተሰርዟል"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"የባትሪ ዕድሜን ለማሻሻል ማገዝ እንዲቻል፣ ኢሜይል፣ መልዕክት አላላክ እና ሌሎች በማመሳሰል ላይ የሚመረኮዙ መተግበሪያዎች እርስዎ ካልከፈቱዋቸው በቀር አይዘምኑም።\n\nየባትሪ ኃይል ቆጣቢ የእርስዎ መሣሪያ ኃይል በሚሞላበት ጊዜ በራስ-ሰር ይጠፋል።"</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"የታገደ፦ እነኝህን ማሳወቂያዎች ፈፅሞ አታሳይ"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"ዝቅተኛ፦ በጸጥታ የማሳወቂያ ዝርዝር የታችኛውን ክፍል አሳይ"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"መደበኛ፦ በጸጥታ እነኝህን ማሳወቂያዎች አሳይ"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"ከፍተኛ፦ የማሳወቂያዎችን ዝርዝር የላይኛውን ክፍል አሳይ እና ድምፅ አሰማ"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"አስቸኳይ፦ ወደ ገጸ ማያው አንሳ እና ድምፅ ቅዳ"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">ለ%1$d ደቂቃዎች (እስከ <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> ድረስ)</item>
       <item quantity="other">ለ%1$d ደቂቃዎች (እስከ <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> ድረስ)</item>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 0c05bc4..b103b1b 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -226,8 +226,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"المساعد الصوتي"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"قفل الآن"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"الوضع الآمن"</string>
     <string name="android_system_label" msgid="6577375335728551336">"‏نظام Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"شخصي"</string>
@@ -1477,6 +1476,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"تم التحديث بواسطة المشرف"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"تم حذف الحزمة عن طريق المشرف"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"للمساعدة في تحسين عمر البطارية، يساعد موفر البطارية في تقليل أداء الجهاز ويفرض قيدًا على الاهتزاز وخدمات الموقع ومعظم بيانات الخلفية. قد لا يتم تحديث البريد الإلكتروني والمراسلة والتطبيقات الأخرى التي تعتمد على المزامنة ما لم تفتحها.\n\nيتم إيقاف موفر البطارية تلقائيًا أثناء شحن الجهاز."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"محظور: عدم عرض هذه الإشعارات مطلقًا"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"منخفض الأهمية: عرض بأسفل قائمة الإشعارات وبدون تنبيه صوتي"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"عادي: عرض هذه الإشعارات بدون تنبيه صوتي"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"عالي الأهمية: عرض بأعلى قائمة الإشعارات مع إصدار تنبيه صوتي"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"عاجل: الظهور سريعًا على الشاشة مع إصدار تنبيه صوتي"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="zero">‏لمدة أقل من دقيقة (%1$d) (حتى <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="two">‏لمدة دقيقتين (%1$d) (حتى <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index 593400e..920068b 100644
--- a/core/res/res/values-az-rAZ/strings.xml
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -1440,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Sizin administrator tərəfindən yeniləndi"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Administratorunuz tərəfindən silinib"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Batareyanın istismar müddətini təkmilləşdirmək üçün batareya qənaəti cihazınızın məhsuldarlığını azaldır və titrətmə, məkan xidmətləri və ən son fon məlumatlarını məhdudlaşdırır. Sinxronlaşmaya arxayın olan e-poçt, mesajlaşma və digər proqramlar siz onları açmayana kimi yenilənməyə bilər.\n\nCihazınız doldurulan zaman batareya qənaəti avtomatik olaraq sönür."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Blok edildi: Bu bildirişləri heç vaxt göstərməyin"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Alçaq: Bildirişlər siyahısının aşağısında səssiz göstərin"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normal: Bu bildişləri səssiz göstərin"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Yüksək: Bildirişlər siyahısında yuxarıda göstərin və səsli edin"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Təcili: Ekranda nəzər salın və səsli edin"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other"> %1$d dəqiqəlik (saat <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> radəsinə qədər)</item>
       <item quantity="one">Bir dəqiqəlik (saat <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> radəsinə qədər)</item>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 50f2938..88b261e 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Гласова помощ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Заключване сега"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Безопасен режим"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Системно от Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Личен"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Актуализирано от администратора ви"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Изтрито от администратора ви"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"С цел удължаване на живота на батерията режимът за запазването й намалява ефективността на устройството ви и ограничава вибрирането, услугите за местоположение и повечето данни на заден план. Приложенията за електронна поща, съобщения и др., които разчитат на синхронизиране, може да не се актуализират, освен ако не ги отворите.\n\nРежимът за запазване на батерията се изключва автоматично, когато устройството ви се зарежда."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Блокирано: Тези известия никога да не се показват"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Маловажно: Показване без звуков сигнал в долната част на списъка с известия"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Нормално: Тези известия да се показват без звуков сигнал"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Важно: Показване в горната част на списъка с известия и издаване на звуков сигнал"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Спешно: Показване на екрана и издаване на звуков сигнал"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">За %1$d минути (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">За една минута (до <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index fdd46172..91244e6 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ভয়েস সহায়তা"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"এখনই লক করুন"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"৯৯৯+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>টি)"</string>
     <string name="safeMode" msgid="2788228061547930246">"নিরাপদ মোড"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android সিস্টেম"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"ব্যক্তিগত"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"আপনার প্রশাসক দ্বারা আপডেট করা হয়েছে"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"আপনার প্রশাসক দ্বারা মুছে ফেলা হয়েছে"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"ব্যাটরির লাইফ উন্নত করতে সহায়তা করতে, ব্যাটারি সাশ্রয়কারী আপনার ডিভাইসের কার্যসম্পাদনা হ্রাস করে এবং কম্পন, অবস্থান পরিষেবাসমূহ এবং অধিকাংশ ব্যাকগ্রাউন্ড ডেটা সীমিত করে৷ ইমেল, বার্তাপ্রেরণ এবং অন্যান্য অ্যাপ্লিকেশানগুলিকে যেগুলি সিঙ্কের উপর নির্ভর করে সেগুলিকে আপনি না খোলা পর্যন্ত নাও আপডেট হতে পারে৷\n\nআপনার ডিভাইসটিকে যখন চার্জ করা হয় তখন ব্যাটারি সাশ্রয়কারী স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যায়৷"</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"অবরুদ্ধ: এই বিজ্ঞপ্তিগুলি কখনই দেখানো হবে না"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"নিম্ন: বিজ্ঞপ্তি তালিকার নীচের অংশে নিঃশব্দে প্রদর্শন করা হয়"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"সাধারন: এই বিজ্ঞপ্তিগুলি নিঃশব্দে প্রদর্শন করা হয়"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"উচ্চ: বিজ্ঞপ্তি তালিকার শীর্ষে দেখানো হয় এবং শব্দ করে"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"জরুরী: স্ক্রীনের উপরে প্রদর্শিত হয় এবং শব্দ করে"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">%1$d মিনিটের জন্য (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> পর্যন্ত)</item>
       <item quantity="other">%1$d মিনিটের জন্য (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> পর্যন্ত)</item>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index cb24d26..0d2b46c 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Assist. per veu"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloqueja ara"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"+999"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mode segur"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"L\'administrador l\'ha actualitzat"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"L\'administrador ho ha suprimit"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Per tal d\'augmentar la durada de la bateria, la funció d\'estalvi de bateria redueix el rendiment del dispositiu i en limita la vibració i la majoria de dades en segon pla. És possible que el correu electrònic, la missatgeria i la resta d\'aplicacions que se sincronitzen amb freqüència no s\'actualitzin llevat que les obris.\n\nL\'estalvi de bateria es desactiva automàticament mentre el dispositiu s\'està carregant."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Bloquejada: no mostra mai aquestes notificacions"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Baixa: mostra de manera silenciosa a la part inferior de la llista de notificacions"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normal: mostra aquestes notificacions de manera silenciosa"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Alta: mostra a la part superior de la llista de notificacions i emet un so"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Urgent: mostra a la pantalla i emet un so"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">Durant %1$d minuts (fins a les <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">Durant 1 minut (fins a les <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index c2f1364..4c554bc 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -224,8 +224,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Hlas. asistence"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Zamknout"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Nouzový režim"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Systém Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Osobní"</string>
@@ -1459,6 +1458,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Aktualizováno administrátorem"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Smazáno administrátorem"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Spořič baterie za účelem prodloužení výdrže baterie snižuje výkon zařízení a omezuje vibrace, služby určování polohy a většinu dat na pozadí. E-mail, aplikace pro zasílání zpráv a další aplikace, které používají synchronizaci, se nemusejí aktualizovat, dokud je neotevřete.\n\nPři nabíjení zařízení se spořič baterie automaticky vypne."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Blokováno: Tato oznámení nikdy nezobrazovat"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Nízká: Tato oznámení zobrazovat na konci seznamu bez zvukového upozornění"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normální: Tato oznámení zobrazovat bez zvukového upozornění"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Vysoká: Tato oznámení zobrazovat na začátku seznamu a upozornit na ně zvukem"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Urgentní: Tato oznámení zobrazovat přímo na obrazovce a upozornit na ně zvukem"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="few">%1$d minuty (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="many">%1$d minuty (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 42cb42b..850b8a2 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1440,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Opdateret af administrator"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Slettet af din administrator"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Batterisparefunktionen hjælper med at forlænge batteriets levetid ved at reducere enhedens ydeevne og begrænse vibration, placeringstjenester og det meste baggrundsdata. E-mail, beskedfunktioner og andre apps, der benytter synkronisering, opdateres muligvis ikke, medmindre du åbner dem.\n\nBatterisparefunktionen slukker automatisk, når enheden oplader."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Blokeret: Vis aldrig disse underretninger"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Lav: Vis lydløst nederst på listen over underretninger"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normal: Vis disse underretninger lydløst"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Høj: Vis øverst på listen over underretninger, og giv lyd"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Presserende: Vis på skærmen, og giv lyd"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">I %1$d minutter (indtil <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="other">I %1$d minutter (indtil <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index d52c728..ab45504 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Sprachassistent"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Jetzt sperren"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Abgesicherter Modus"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android-System"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Privat"</string>
@@ -245,7 +244,7 @@
     <string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"Telefonanrufe zu tätigen und zu verwalten"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"Körpersensoren"</string>
-    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"Auf Sensordaten zu Ihren Vitaldaten zugreifen"</string>
+    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"auf Sensordaten zu Ihren Vitaldaten zuzugreifen"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Fensterinhalte abrufen"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Die Inhalte eines Fensters, mit dem Sie interagieren, werden abgerufen."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"\"Tippen &amp; Entdecken\" aktivieren"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Von Ihrem Administrator aktualisiert"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Von Ihrem Administrator gelöscht"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Der Energiesparmodus schont den Akku, indem er die Leistung des Geräts reduziert und die Vibrationsfunktion sowie die meisten Hintergrunddatenaktivitäten einschränkt. E-Mail, SMS/MMS und andere Apps, die auf Ihrem Gerät synchronisiert werden, werden möglicherweise erst nach dem Öffnen aktualisiert.\n\nDer Energiesparmodus wird automatisch deaktiviert, wenn Ihr Gerät aufgeladen wird."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Blockiert: Keine Benachrichtigungen anzeigen"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Niedrig: Benachrichtigungen ganz unten in der Benachrichtigungsliste und ohne Ton anzeigen"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normal: Benachrichtigungen ohne Ton anzeigen"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Hoch: Benachrichtigungen ganz oben in der Benachrichtigungsliste und mit Ton anzeigen"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Dringend: Mit Ton auf dem Display einblenden"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">%1$d Minuten (bis <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">1 Minute (bis <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index f86c2fd..d5fdd29 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Φων.υποβοηθ."</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Κλείδωμα τώρα"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Ασφαλής λειτουργία"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Σύστημα Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Προσωπικό"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Ενημερώθηκε από το διαχειριστή σας"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Διαγράφηκε από το διαχειριστή σας"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Προκειμένου να βελτιώσει τη διάρκεια ζωής της μπαταρίας σας, η Εξοικονόμηση μπαταρίας μειώνει την απόδοση της συσκευής σας και περιορίζει λειτουργίες όπως η δόνηση, οι υπηρεσίες τοποθεσίας και τα περισσότερα δεδομένα παρασκηνίου. Το ηλεκτρονικό ταχυδρομείο, η ανταλλαγή μηνυμάτων και άλλες εφαρμογές που βασίζονται στο συγχρονισμό ενδέχεται να μην ενημερώνονται έως ότου τις ανοίξετε.\n\nΗ Εξοικονόμηση μπαταρίας απενεργοποιείται αυτόματα όταν η συσκευή σας φορτίζει."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Αποκλεισμένες: Να μην εμφανίζονται ποτέ αυτές οι ειδοποιήσεις"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Χαμηλής βαρύτητας: Να εμφανίζονται στο κάτω τμήμα της λίστας ειδοποιήσεων χωρίς τη συνοδεία ήχου"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Κανονική βαρύτητα: Να εμφανίζονται αυτές οι ειδοποιήσεις χωρίς ήχο"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Υψηλής βαρύτητας: Να εμφανίζονται στην κορυφή της λίστας ειδοποιήσεων συνοδευόμενες από κάποιον ήχο"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Επείγουσες: Να προβάλλονται στην οθόνη και να συνοδεύονται από κάποιον ήχο"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">Για %1$d λεπτά (έως τις <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">Για ένα λεπτό (έως τις <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index e23f8d5..6c20763 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1440,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Updated by your administrator"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Deleted by your administrator"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"To help improve battery life, battery saver reduces your device’s performance and limits vibration, location services and most background data. Email, messaging, and other apps that rely on syncing may not update unless you open them.\n\nBattery saver turns off automatically when your device is charging."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Blocked: Never show these notifications"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Low: Silently show at the bottom of the notification list"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normal: Silently show these notifications"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"High: Show at the top of the notifications list and make sound"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Urgent: Peek onto the screen and make sound"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">For %1$d minutes (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">For one minute (until <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index e23f8d5..6c20763 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1440,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Updated by your administrator"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Deleted by your administrator"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"To help improve battery life, battery saver reduces your device’s performance and limits vibration, location services and most background data. Email, messaging, and other apps that rely on syncing may not update unless you open them.\n\nBattery saver turns off automatically when your device is charging."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Blocked: Never show these notifications"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Low: Silently show at the bottom of the notification list"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normal: Silently show these notifications"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"High: Show at the top of the notifications list and make sound"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Urgent: Peek onto the screen and make sound"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">For %1$d minutes (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">For one minute (until <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index e23f8d5..6c20763 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1440,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Updated by your administrator"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Deleted by your administrator"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"To help improve battery life, battery saver reduces your device’s performance and limits vibration, location services and most background data. Email, messaging, and other apps that rely on syncing may not update unless you open them.\n\nBattery saver turns off automatically when your device is charging."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Blocked: Never show these notifications"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Low: Silently show at the bottom of the notification list"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normal: Silently show these notifications"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"High: Show at the top of the notifications list and make sound"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Urgent: Peek onto the screen and make sound"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">For %1$d minutes (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">For one minute (until <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index b442bc1f..4e2029f 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Asistente voz"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear ahora"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
@@ -237,7 +236,7 @@
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"enviar y ver mensajes SMS"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Espacio de almacenamiento"</string>
-    <string name="permgroupdesc_storage" msgid="637758554581589203">"acceder a las fotos, el contenido multimedia y los archivos del dispositivo"</string>
+    <string name="permgroupdesc_storage" msgid="637758554581589203">"acceder a las fotos, el contenido multimedia y los archivos"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"Micrófono"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"grabar audio"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"Cámara"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Actualizado por el administrador"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Lo eliminó el administrador."</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Para ayudar a mejorar la duración de la batería, el ahorro de batería reduce el rendimiento del dispositivo y limita la vibración, los servicios de ubicación y la mayoría de los datos en segundo plano. Es posible que el correo electrónico, la mensajería y otras aplicaciones que se basan en la sincronización no puedan actualizarse, a menos que los abras.\n\nEl ahorro de batería se desactiva de forma automática cuando el dispositivo se está cargando."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Bloqueada: no mostrar nunca estas notificaciones"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Baja: mostrar en la parte inferior de la lista de notificación sin emitir sonido"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normal: mostrar estas notificaciones de manera silenciosa"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Alta: mostrar en la parte superior de la lista de notificaciones y emitir sonido"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Urgente: mostrar en la pantalla y emitir sonido"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">Durante %1$d minutos hasta la(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g></item>
       <item quantity="one">Durante 1 minuto; hasta la(s) <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g></item>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index acbef23..4868f6b 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Asistente voz"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear ahora"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt; 999"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Actualizado por tu administrador"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Eliminado por tu administrador"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Para ayudar a mejorar la duración de la batería, la función de ahorro de energía reduce el rendimiento del dispositivo y limita la vibración, los servicios de ubicación y la mayor parte de la transmisión de datos en segundo plano. Es posible que las aplicaciones que se sincronizan, como las de correo y mensajes, no se actualicen a menos que las abras.\n\nLa función de ahorro de energía se desactiva automáticamente cuando el dispositivo se está cargando."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Bloqueada: no mostrar estas notificaciones"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Baja: mostrar en la parte inferior de la lista de notificaciones de forma silenciosa"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normal: mostrar estas notificaciones de forma silenciosa"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Alta: mostrar en la parte superior de la lista de notificaciones y emitir sonido"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Urgente: mostrar en la pantalla y emitir sonido"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">Durante %1$d minutos (hasta las <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">Durante un minuto (hasta las <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 9a96683..3bbdcdf 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Häälabi"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Lukusta kohe"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Turvarežiim"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android-süsteem"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Isiklik"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Värskendas administraator"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Kustutas teie administraator"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Aku kestuse parandamiseks vähendab akusäästja teie seadme toimivust ning piirab vibratsiooni, asukohateenuseid ja suuremat osa taustaandmetest. E-posti, sõnumsidet ja muid sünkroonimisele tuginevaid rakendusi võidakse värskendada ainult siis, kui te need avate.\n\nAkusäästja lülitatakse seadme laadimise ajal automaatselt välja."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Blokeeritud: ära kunagi näita neid märguandeid"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Madal: kuva vaikselt märguannete loendi allosas"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Tavaline: kuva need märguanded vaikselt"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Kõrge: kuva märguannete loendi ülaosas koos heliga"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Kiireloomuline: kuva ekraani servas koos heliga"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">%1$d minutiks (kuni <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">Üheks minutiks (kuni <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index a30c437..13c8720 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Ahots-laguntza"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Blokeatu"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modu segurua"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android sistema"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Pertsonalak"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Administratzaileak eguneratu du"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Administratzaileak ezabatu du"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Bateriak gehiago iraun dezan, bateria-aurrezleak gailuaren funtzionamendua, dardara,  kokapen-zerbitzuak eta atzeko planoko datuen erabilera gehiena mugatzen ditu. Posta elektronikoa, mezuak eta sinkronizatzen diren gainerako zerbitzuak ez dira eguneratuko ireki ezean.\n\nGailua kargatzen ezarri orduko desaktibatzen da bateria-aurrezlea."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Blokeatuta: ez erakutsi jakinarazpen hauek"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Txikia: erakutsi jakinarazpen hauek zerrendaren behealdean"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normala: erakutsi jakinarazpen hauek, baina soinurik egin gabe"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Handia: erakutsi jakinarazpen hauek zerrendaren goialdean eta egin soinua"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Premiazkoa: agerrarazi jakinarazpen hauek pantailan eta egin soinua"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">%1$d minutuz (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> arte)</item>
       <item quantity="one">Minutu batez (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> arte)</item>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 8672171..9cbb29b 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"دستیار صوتی"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"اکنون قفل شود"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"بیشتر از 999"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"حالت ایمن"</string>
     <string name="android_system_label" msgid="6577375335728551336">"‏سیستم Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"شخصی"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"توسط سرپرست شما به‌روزرسانی شد"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"توسط سرپرستتان حذف شد"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"برای کمک به بهبود عمر باتری، بهینه‌سازی باتری عملکرد دستگاهتان را کاهش می‌دهد و لرزش، سرویس‌های مبتنی بر مکان، و دسترسی به اکثر داده‌ها در پس‌زمینه را محدود می‌کند. ایمیل، پیام‌رسانی و برنامه‌های دیگری که به همگام‌سازی وابسته‌اند، تا زمانی‌که آن‌ها را باز نکنید نمی‌توانند به‌روز شوند.\n\nبهینه‌سازی باتری به‌صورت خودکار در هنگام شارژ شدن دستگاه خاموش می‌شود."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"مسدود: هرگز این اعلان‌ها نشان داده نشود"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"پایین: بدون صدا در پایین فهرست اعلان نشان داده شود"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"عادی: این اعلان‌ها بدون صدا نشان داده شود"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"بالا: در بالای فهرست اعلان‌ها و به همراه صدا نشان داده شود"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"ضروری: نمای کلی به همراه صدا در صفحه نشان داده شود"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">‏به مدت %1$d دقیقه (تا <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="other">‏به مدت %1$d دقیقه (تا <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 8100305..34b5fad 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Ääniapuri"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Lukitse nyt"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Suojattu tila"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android-järjestelmä"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Henkilökoht."</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Järjestelmänvalvojasi on päivittänyt paketin."</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Järjestelmänvalvoja on poistanut paketin."</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Jos haluat parantaa akun kestoa, virransäästö vähentää laitteesi suorituskykyä ja rajoittaa värinää, sijaintipalveluita ja useimpia taustatietoja. Sähköposti, viestit ja muut synkronointiin perustuvat sovellukset eivät välttämättä päivity, ellet avaa niitä.\n\nVirransäästö poistuu käytöstä automaattisesti, kun laitteesi latautuu."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Estetty: älä koskaan näytä näitä ilmoituksia."</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Matala: näytä nämä ilmoitukset huomaamattomasti luettelon alaosassa."</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Tavallinen: näytä nämä ilmoitukset huomaamattomasti."</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Korkea: näytä nämä ilmoitukset luettelon yläosassa ja toista äänimerkki."</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Kiireellinen: näytä ilmoitus näytöllä ja toista äänimerkki."</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">%1$d minuutiksi (kunnes kello on <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">Yhdeksi minuutiksi (kunnes kello on <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index b273980..9dad4c0 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Assist. vocale"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Verrouiller"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mode sécurisé"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Système Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Personnel"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Mis à jour par votre administrateur"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Supprimé par votre administrateur"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Pour améliorer l\'autonomie de la pile, la fonction d\'économie d\'énergie réduit les performances de votre appareil et limite la vibration, les services de localisation ainsi que la plupart des données en arrière-plan. Les applications Courriel, Messages et d\'autres qui reposent sur la synchronisation ne peuvent pas se mettre à jour, sauf si vous les ouvrez. \n\n L\'économiseur d\'énergie se désactive automatiquement lorsque votre appareil est en charge."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Bloquée : ne jamais afficher ces notifications"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Faible : afficher en mode silencieux au bas de la liste de notifications"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normale : afficher ces notifications en mode silencieux"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Élevée : afficher en haut de la liste des notifications et émettre un son"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Urgent : afficher sur l\'écran et émettre un son"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">Pendant %1$d minute (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="other">Pendant %1$d minutes (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 850c18a..dc08738 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Assistance vocale"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Verrouiller"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mode sécurisé"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Système Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Personnel"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Mis à jour par votre administrateur"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Supprimé par votre administrateur"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Pour améliorer l\'autonomie de la batterie, l\'économiseur de batterie réduit les performances et désactive le vibreur, les services de localisation et la plupart des données en arrière-plan. Les messageries électroniques ou autres applications utilisant la synchronisation pourraient ne pas se mettre à jour, sauf si vous les ouvrez.\n\nL\'économiseur de batterie s\'éteint automatiquement lorsque l\'appareil est en charge."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Bloquée : ne jamais afficher ces notifications"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Faible : afficher en mode silencieux au bas de la liste de notifications"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normale : afficher ces notifications en mode silencieux"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Élevée : afficher en haut de la liste des notifications et émettre un son"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Urgent : afficher sur l\'écran et émettre un son"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">Pendant %1$d minute (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="other">Pendant %1$d minutes (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index 998f494..02ee7b45 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Asistente voz"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear agora"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Persoal"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Actualizado polo administrador"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Eliminado polo administrador"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Para axudar a mellorar a duración da batería, a función aforro de batería reduce o rendemento do teu dispositivo e limita a vibración, os servizos de localización e a maioría dos datos en segundo plano. É posible que o correo electrónico, as mensaxes e outras aplicacións que dependen da sincronización non se actualicen a menos que os abras. \n\nA función aforro de batería desactívase automaticamente cando pos a cargar o teu dispositivo."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Bloqueada: non mostrar nunca estas notificacións"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Baixa: mostrar de forma silenciosa na parte inferior da lista de notificacións"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normal: mostrar estas notificacións de forma silenciosa"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Alta: mostrar na parte superior da lista de notificacións e emitir son"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Urxente: mostrar na pantalla e emitir son"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">Durante %1$d minutos (ata as <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">Durante un minuto (ata as <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml
index 7cfd200..c1187df 100644
--- a/core/res/res/values-gu-rIN/strings.xml
+++ b/core/res/res/values-gu-rIN/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"વૉઇસ સહાય"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"હવે લૉક કરો"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"સુરક્ષિત મોડ"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android સિસ્ટમ"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"વ્યક્તિગત"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"તમારા વ્યવસ્થાપક દ્વારા અપડેટ થયેલ"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"તમારા વ્યવસ્થાપક દ્વારા કાઢી નાખેલ"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"બૅટરી આવરદા વધુ સારી કરવામાં સહાય માટે, બૅટરી સેવર તમારા ઉપકરણના પ્રદર્શનને ઘટાડે છે અને વાઇબ્રેશન, સ્થાન સેવાઓ અને મોટાભાગના પૃષ્ઠભૂમિ ડેટાને સીમિત કરે છે. ઇમેઇલ, મેસેજિંગ અને અન્ય એપ્લિકેશનો જે સમન્વયન પર આધાર રાખે છે તે તમે તેમને ખોલશો નહીં ત્યાં સુધી અપડેટ થઈ શકતી નથી.\n\nજ્યારે તમારું ઉપકરણ ચાર્જ થઈ રહ્યું હોય ત્યારે બૅટરી સેવર આપમેળે બંધ થઈ જાય છે."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"અવરોધિત: આ સૂચનાઓ ક્યારેય બતાવશો નહીં"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"નિમ્ન: સૂચનાની સૂચિની નીચે ચુપચાપ બતાવો"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"સામાન્ય: આ સૂચનાઓ ચુપચાપ બતાવો"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"ઉચ્ચ: સૂચનાઓની સૂચિની ટોચ પર બતાવો અને અવાજ કરો"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"તાત્કાલિક : સ્ક્રીન પર ત્વરિત દ્રષ્ટિ કરો અને અવાજ કરો"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">%1$d મિનિટ માટે (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> સુધી)</item>
       <item quantity="other">%1$d મિનિટ માટે (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> સુધી)</item>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index a001211..e81872a 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"वॉइस सहायक"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"अभी लॉक करें"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android सिस्‍टम"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"व्यक्तिगत"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"आपके नियंत्रक द्वारा अपडेट किया गया"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"आपके नियंत्रक द्वारा हटाया गया"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"बैटरी जीवन काल को बेहतर बनाने में सहायता के लिए, बैटरी सेवर आपके डिवाइस के प्रदर्शन को कम कर देता है और कंपन, स्‍थान सेवाओं और अधिकांश पृष्‍ठभूमि डेटा को सीमित कर देता है. हो सकता है कि ईमेल, संदेश सेवा तथा समन्‍वयन पर आधारित अन्‍य ऐप्‍स तब तक ना खुलें जब तक कि आप उन्‍हें नहीं खोलते.\n\nजब आपका डिवाइस चार्ज हो रहा होता है तो बैटरी सेवर अपने आप बंद हो जाता है."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"अवरोधित: ये नोटिफिकेशन कभी ना दिखाएं"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"निम्‍न: नोटिफिकेशन सूची के नीचे मौन रूप से दिखाएं"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"सामान्‍य: ये नोटिफिकेशन मौन रूप से दिखाएं"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"उच्‍च: नोटिफिकेशन सूची के शीर्ष पर दिखाएं और ध्‍वनि करें"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"तत्‍काल: स्‍क्रीन पर एक झलक देखें और ध्‍वनि करें"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">%1$d मिनट के लिए (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> तक)</item>
       <item quantity="other">%1$d मिनट के लिए (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> तक)</item>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 55399af..f53625e 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -223,8 +223,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Glasovna pomoć"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Zaključaj sada"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Siguran način rada"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sustav Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Osobno"</string>
@@ -1450,6 +1449,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Ažurira vaš administrator"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Izbrisao administrator"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Da bi se produljilo trajanje baterije, ušteda baterije smanjuje rad uređaja i ograničava vibraciju, usluge lokacije i većinu pozadinskih podataka. Aplikacije za e-poštu, slanje poruka i druge aplikacije koje se oslanjaju na sinkronizaciju možda se neće ažurirati ako ih ne otvorite.\n\nUšteda baterije isključuje se automatski dok se uređaj puni."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Blokirano: nikad ne prikazuj te obavijesti"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Nisko: tiho prikaži na dnu popisa obavijesti"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Uobičajeno: prikazuj te obavijesti tiho"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Visoko: prikaži na vrhu popisa obavijesti i emitiraj zvučni signal"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Hitno: prikaži na zaslonu i emitiraj zvučni signal"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">%1$d minutu (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="few">%1$d minute (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index dc87943..2bb8fb0 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Hangsegéd"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Zárolás most"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Biztonsági üzemmód"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android rendszer"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Személyes"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Frissítette a rendszergazda"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"A rendszergazda törölte"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Az akkumulátoridő növelése érdekében az energiatakarékos mód csökkenti az eszköz teljesítményét, és korlátozza a rezgést, a helyszolgáltatásokat, valamint a legtöbb háttéradatot is. Előfordulhat, hogy azok az e-mail-, üzenetküldő és egyéb alkalmazások, amelyek szinkronizálására számít, csak akkor frissítenek, ha megnyitja azokat.\n\nAz energiatakarékos mód automatikusan kikapcsol, ha eszköze töltőn van."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Letiltva: soha nem jelennek meg ezek az értesítések"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Alacsony: az értesítések az értesítési lista végén jelennek meg hangjelzés nélkül"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normál: hang nélkül jelennek meg ezek az értesítések"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Magas: az értesítések az értesítési lista elején jelennek meg hangjelzéssel"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Sürgős: az értesítések felugranak a képernyőn hangjelzéssel"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">%1$d percen át (eddig: <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">Egy percen át (eddig: <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index f1d32d8..257d435 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Ձայնային օգնութ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Կողպել հիմա"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Անվտանգ ռեժիմ"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android համակարգ"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Անձնական"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Ադմինիստրատորը թարմացրել է այն"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Ադմինիստրատորը ջնջել է այն"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Մարտկոցի աշխատանքի ժամկետը երկարացնելու նպատակով, մարտկոցի էներգիայի խնայման գործառույթը սահմանափակում է սարքի աշխատանքը, թրթռոցը, տեղադրության ծառայությունները և հետնաշերտում աշխատող շատ գործընթացներ: Էլփոստը, հաղորդագրությունների փոխանակումը և տվյալների համաժամեցումից կախված այլ հավելվածները կարող են չթարմացվել, եթե դուք դրանք չգործարկեք:\n\nԵրբ ձեր սարքը լիցքավորվում է, մարտկոցի էներգիայի խնայման գործառույթն ինքնաշխատորեն անջատվում է:"</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Արգելափակված է. Երբեք չցուցադրել այս ծանուցումները"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Ցածր. Ցուցադրել ծանուցումների ցանկի ներքևում առանց ձայնային ազդանշանի"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Նորմալ. Ցուցադրել այս ծանուցումներն առանց ձայնային ազդանշանի"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Բարձր. Ցուցադրել ծանուցումների ցանկի վերևում և հնչեցնել ձայնային ազդանշան"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Հրատապ. Ցուցադրել էկրանին և հնչեցնել ձայնային ազդանշան"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">%1$d րոպե (մինչև <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="other">%1$d րոպե (մինչև <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 8e18dae..6be50d5 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Bantuan Suara"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Kunci sekarang"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mode aman"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Pribadi"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Diperbarui oleh administrator"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Dihapus oleh administrator"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Untuk membantu meningkatkan masa pakai baterai, penghemat baterai mengurangi kinerja perangkat dan membatasi getaran, layanan lokasi, dan kebanyakan data latar belakang. Email, perpesanan, dan aplikasi lain yang mengandalkan sinkronisasi mungkin tidak diperbarui kecuali jika dibuka.\n\nPenghemat baterai otomatis nonaktif jika perangkat diisi dayanya."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Diblokir: Jangan pernah menampilkan notifikasi ini"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Rendah: Menampilkan di bagian bawah daftar notifikasi secara diam-diam"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normal: Menampilkan notifikasi ini secara diam-diam"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Tinggi: Menampilkan di bagian atas daftar notifikasi dan membunyikan suara"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Darurat: Muncul di layar dan membunyikan suara"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">Selama %1$d menit (hingga <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">Selama satu menit (hingga <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index b2c98f0..c2b8a8c 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Raddaðstoð"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Læsa núna"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Örugg stilling"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android kerfið"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Persónulegt"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Uppfært af kerfisstjóranum"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Eytt af kerfisstjóra"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Til að auka endingu rafhlöðunnar mun orkusparnaður draga úr afköstum tækisins og takmarka titring, staðsetningarþjónustu og megnið af bakgrunnsgögnum. Ekki er víst að tölvupóstur, skilaboð og önnur forrit sem reiða sig á samstillingu uppfærist nema þú opnir þau.\n\nSjálfkrafa er slökkt á orkusparnaði þegar tækið er í hleðslu."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Útilokaðar: Aldrei sýna þessar tilkynningar"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Léttvægar: Sýna neðst á tilkynningalistanum án hljóðs"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Venjulegar: Sýna þessar tilkynningar án hljóðs"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Mikilvægar: Sýna efst á tilkynningalistanum og spila hljóð"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Áríðandi: Birta á skjánum og spila hljóð"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">Í %1$d mínútu (til <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="other">Í %1$d mínútur (til <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index b36e2e5..c4614fc 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1440,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Aggiornato dall\'amministratore"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Eliminato dall\'amministratore"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Per aumentare la durata della batteria, la funzione di risparmio energetico riduce le prestazioni del dispositivo e limita vibrazione, servizi di localizzazione e la maggior parte dei dati in background. App di email, messaggi e altre app che si basano sulla sincronizzazione potrebbero essere aggiornate soltanto all\'apertura.\n\nLa funzione di risparmio energetico viene disattivata automaticamente quando il dispositivo è in carica."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Bloccato: non mostrare mai queste notifiche"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Bassa: mostra silenziosamente alla fine dell\'elenco di notifiche"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normale: mostra silenziosamente queste notifiche"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Alta: mostra all\'inizio dell\'elenco di notifiche e riproduci suono"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Urgente: apri sullo schermo e riproduci suono"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">Per %1$d minuti (fino alle ore <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">Per un minuto (fino alle ore <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index cf4ca52..f615187 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -224,8 +224,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"נעל עכשיו"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"מצב בטוח"</string>
     <string name="android_system_label" msgid="6577375335728551336">"‏מערכת Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"אישי"</string>
@@ -1459,6 +1458,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"עודכן על ידי מנהל המערכת שלך"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"נמחקה על ידי מנהל המערכת שלך"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"כדי לעזור בשיפור חיי הסוללה, תכונת החיסכון בסוללה מצמצמת את פעולות המכשיר ומגבילה רטט, שירותי מיקום ואת רוב נתוני הרקע. אימייל, העברת הודעות ואפליקציות אחרות המסתמכות על סנכרון עשויות שלא להתעדכן, אלא אם תפתח אותן.\n\nתכונת החיסכון בסוללה מושבתת אוטומטית כשהמכשיר בטעינה."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"חסימה: לעולם אל תציג הודעות אלה"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"נמוכה: הצג בתחתית רשימת ההודעות בלי להשמיע צליל"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"רגילה: הצג הודעות אלה בלי להשמיע צליל"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"גבוהה: הצג בראש רשימת ההודעות והשמע צליל"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"דחופה: הצג לרגע על המסך והשמע צליל"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="two">‏למשך %d דקות (עד <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="many">‏למשך %1$d דקות (עד <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 1ebf699..6dd4e9a 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1440,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"管理者によって更新されています"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"管理者によって削除されました"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"バッテリーを長持ちさせるため、バッテリーセーバーは端末のパフォーマンスを抑え、バイブレーション、位置情報サービス、大半のバックグラウンドデータを制限します。メール、SMSや、同期を使用するその他のアプリは、起動しても更新されないことがあります。\n\nバッテリーセーバーは端末の充電中は自動的にOFFになります。"</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"ブロック: 今後はこの通知を表示しない"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"低: 通知リストの下にマナーモードで表示する"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"標準: この通知をマナーモードで表示する"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"高: 通知リストの上に表示し、音声でも知らせる"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"緊急: 画面にプレビューを表示し、音声でも知らせる"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">%1$d分間(<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>まで)</item>
       <item quantity="one">1分間(<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>まで)</item>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 604323a..6709d92 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ხმოვანი ასისტ."</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ახლა ჩაკეტვა"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"უსაფრთხო რეჟიმი"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android-ის სისტემა"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"პირადი"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"განახლებულია თქვენი ადმინისტრატორის მიერ"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"თქვენი ადმინისტრატორის მიერ წაშლილი"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"ელემენტის მოქმედების ვადის გაუმჯობესებისათვის, ელემენტის დამზოგი ამცირებს თქვენი მოწყობილობის შესრულებას და ზღუდავს ვიბრაციას, ადგილმდებარეობის მომსახურებებს და ძირითად ფონურ მონაცემებს. ელ-ფოსტა, შეტყობინებები და სხვა სინქრონიზაციაზე დაყრდნობილი აპლიკაციების განახლება არ მოხდება მათ გახსნეამდე. \n\n ელემენტის დამზოგველი ავტომატურად გამოირთვება, როდესაც თქვენს მოწყობილობას დამტენთან შეაერთებთ."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"დაბლოკილი: ეს შეტყობინებები აღარასოდეს გამოჩნდება"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"დაბალი: ეს შეტყობინებები სიის ბოლოში, უხმოდ გამოჩნდება"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"ნორმალური: ეს შეტყობინებები უხმოდ გამოჩნდება"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"მაღალი: ეს შეტყობინებები სიის თავში, ხმოვან სიგნალთან ერთად გამოჩნდება"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"გადაუდებელი: შეტყობინებები პირდაპირ ეკრანზე, ხმოვან სიგნალთან ერთად გამოჩნდება"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">%1$d წუთის განმავლობაში (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>-მდე)</item>
       <item quantity="one">ერთი წუთის განმავლობაში (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>-მდე)</item>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 323be5d..8d12034 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Дауыс көмекшісі"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Қазір бекіту"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Қауіпсіз режим"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android жүйесі"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Жеке"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Әкімші жаңартты"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Әкімші жойған"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Батареяның қызмет көрсету мерзімін жақсарту үшін батарея үнемдегіш құрылғының өнімділігін төмендетеді және дірілді, орынды анықтау қызметтерін және фондық деректердің көпшілігін шектейді. Электрондық пошта, хабар алмасу және синхрондауға негізделген басқа қолданбалар ашқанша жаңартылмауы мүмкін.\n\nБатарея үнемдегіш құрылғы зарядталып жатқанда автоматты түрде өшеді."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Бұғатталған: осы хабарландыруларды ешқашан көрсетпеу"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Төмен: хабарландырулар тізімнің төменгі жағында үнсіз көрсету"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Қалыпты: осы хабарландыруларды үнсіз көрсету"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Жоғары: хабарландырулар тізімінің жоғарғы жағында көрсету және дыбыс шығару"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Шұғыл: экранға бекіту және дыбыс шығару"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">%1$d минут бойы (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> дейін)</item>
       <item quantity="one">Бір минут бойы (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> дейін)</item>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index c00bc14..dcaf305 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ជំនួយសម្លេង"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ចាក់សោ​ឥឡូវនេះ"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"របៀប​​​សុវត្ថិភាព"</string>
     <string name="android_system_label" msgid="6577375335728551336">"ប្រព័ន្ធ​​ Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"ផ្ទាល់ខ្លួន"</string>
@@ -1443,6 +1442,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"បានធ្វើបច្ចុប្បន្នភាពដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"បានលុបដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"ដើម្បីជួយឲ្យថាមពលថ្មប្រសើរឡើង កម្មវិធីសន្សំសំចៃថាមពលថ្មកាត់បន្ថយប្រតិបត្តិការឧបករណ៍របស់អ្នក និងកម្រិតភាពញ័រ សេវាកម្មទីតាំង និងទិន្នន័យផ្ទៃខាងក្រោយស្ទើរតែទាំងអស់។ ការផ្ញើសារអ៊ីម៉ែល និងកម្មវិធីផ្សេងទៀតដែលពឹងផ្អែកលើការធ្វើសមកាលកម្មអាចនឹងមិនធ្វើបច្ចុប្បន្នភាពទេ លុះត្រាតែអ្នកបើកពួកវា។\n\nកម្មវិធីសន្សំសំចៃបិទដោយស្វ័យប្រវត្តិ នៅពេលដែលឧបករណ៍របស់អ្នកកំពុងសាកថ្ម។"</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"បានរារាំង៖ កុំបង្ហាញការជូនដំណឹងទាំងនេះ"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"កម្រិតទាប៖ បង្ហាញស្ងាត់ៗនៅផ្នែកខាងក្រោមបញ្ជីនៃការជូនដំណឹង"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"ធម្មតា៖ បង្ហាញការជូនដំណឹងទាំងនេះស្ងាត់ៗ"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"កម្រិតខ្ពស់៖ បង្ហាញនៅផ្នែកខាងលើបញ្ជីនៃការជូនដំណឹង និងបន្លឺសំឡេង"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"បន្ទាន់៖ លោតបង្ហាញនៅលើអេក្រង់ និងបន្លឺសំឡេង"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">រយៈពេល %1$d នាទី (រហូតដល់ <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">រយៈពេលមួយនាទី (រហូតដល់ <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index 1aba0bb..e7ad010 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ಧ್ವನಿ ಸಹಾಯಕ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ಈಗ ಲಾಕ್ ಮಾಡಿ"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"ಸುರಕ್ಷಿತ ಮೋಡ್"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android ಸಿಸ್ಟಂ"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"ವೈಯಕ್ತಿಕ"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರಿಂದ ನವೀಕರಿಸಲಾಗಿದೆ"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರಿಂದ ಅಳಿಸಲಾಗಿದೆ"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"ನಿಮ್ಮ ಬ್ಯಾಟರಿಯ ಬಾಳಿಕೆಯನ್ನು ಸುಧಾರಿಸಲು ಸಹಾಯ ಮಾಡಲು, ಬ್ಯಾಟರಿ ಉಳಿಕೆಯು ನಿಮ್ಮ ಸಾಧನದ ಕಾರ್ಯಕ್ಷಮತೆಯನ್ನು ಕಡಿಮೆ ಮಾಡುತ್ತದೆ ಮತ್ತು ವೈಬ್ರೇಷನ್, ಸ್ಥಳ ಸೇವೆಗಳು ಹಾಗೂ ಹೆಚ್ಚಿನ ಹಿನ್ನೆಲೆ ಡೇಟಾವನ್ನು ಮಿತಿಗೊಳಿಸುತ್ತದೆ. ಸಿಂಕ್ ಮಾಡುವುದನ್ನು ಅವಲಂಬಿಸಿರುವ ಇಮೇಲ್, ಸಂದೇಶ ಕಳುಹಿಸುವಿಕೆ, ಮತ್ತು ಇತರ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ನೀವು ತೆರೆಯದ ಹೊರತು ನವೀಕರಣಗೊಳ್ಳುವುದಿಲ್ಲ.\n\nನಿಮ್ಮ ಸಾಧನವು ಚಾರ್ಜ್ ಆಗುತ್ತಿರುವ ಸಮಯದಲ್ಲಿ ಬ್ಯಾಟರಿ ಉಳಿಕೆಯು ಆಫ್ ಆಗುತ್ತದೆ."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ: ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ಎಂದಿಗೂ ತೋರಿಸಬೇಡ"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"ಕಡಿಮೆ: ಅಧಿಸೂಚನೆ ಪಟ್ಟಿಯ ಕೆಳಭಾಗದಲ್ಲಿ ಸ್ಥಬ್ಧವಾಗಿ ತೋರಿಸು"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"ಸಾಮಾನ್ಯ: ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ಸ್ಥಬ್ಧವಾಗಿ ತೋರಿಸು"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"ಅಧಿಕ: ಅಧಿಸೂಚನೆಗಳ ಪಟ್ಟಿಯ ಮೇಲ್ಭಾಗದಲ್ಲಿ ತೋರಿಸು ಮತ್ತು ಧ್ವನಿ ಮಾಡು"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"ತುರ್ತು: ಪರದೆಯನ್ನು ವೀಕ್ಷಿಸಿ ಮತ್ತು ಧ್ವನಿ ಮಾಡು"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">%1$d ನಿಮಿಷಗಳವರೆಗೆ (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> ವರೆಗೆ)</item>
       <item quantity="other">%1$d ನಿಮಿಷಗಳವರೆಗೆ (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> ವರೆಗೆ)</item>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 3384f09..85f46d1 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"음성 지원"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"지금 잠그기"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>개)"</string>
     <string name="safeMode" msgid="2788228061547930246">"안전 모드"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android 시스템"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"개인"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"관리자에 의해 업데이트됨"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"관리자가 삭제함"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"배터리 수명 개선을 위해, 배터리 세이버는 기기의 성능을 줄이고 진동, 위치 서비스 및 대부분의 백그라운드 데이터를 제한합니다. 이메일, 메시지 및 동기화에 의존하는 기타 앱은 앱을 열 때까지 업데이트되지 않을 수 있습니다.\n\n배터리 세이버는 기기를 충전 중일 때는 자동으로 사용 중지됩니다."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"차단: 알림 다시 표시 안함"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"낮음: 알림 목록 하단에 무음으로 표시"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"일반: 무음으로 알림 표시"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"높음: 알림 목록 상단에 표시하고 소리로 알림"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"긴급: 화면에 표시하고 소리로 알림"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">%1$d분 동안(<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>까지)</item>
       <item quantity="one">1분 동안(<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>까지)</item>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 870c858..bb1cd7f 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Үн жардамчысы"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Азыр кулпулоо"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Коопсуз режим"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android Тутуму"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Жеке"</string>
@@ -1442,6 +1441,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Администраторуңуз жаңырткан"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Администраторуңуз тарабынан жок кылынган"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Батареянын өмүрүн узартуу үчүн, батареяны үнөмдөгүч түзмөгүңүздүн ишинин майнаптуулугун азайтып, дирилдөө, жайгашкан жерди аныктоо кызматтары жана фондук дайындардын көпчүлүгүн чектеп коёт. Электрондук почта, билдирүү жазышуу жана башка шайкештештирүүгө байланыштуу колдонмолор ачылмайынча жаңыртылбай калышы мүмкүн.\n\nБатарея үнөмдөгүч түзмөгүңүз кубатталып жатканда автоматтык түрдө өчүп калат."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Бөгөттөлгөн: Бул эскертмелер эч качан көрсөтүлбөсүн"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Төмөн: Эскертмелер тизмесинин эң ылдыйында көрсөтүлсүн"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Кадимки: Бул эскертмелер акырын көрсөтүлсүн"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Жогору: Эскертмелер тизмесинин эң жогорусунда үн чыгарып көрсөтүлсүн"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Шашылыш: Үн менен коштолуп, экранга чыгарылсын"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">%1$d мүнөткө (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> чейин)</item>
       <item quantity="one">Бир мүнөткө (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> чейин)</item>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index d5484d3..bc58ea6 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ຊ່ວຍ​ເຫຼືອ​ທາງ​ສຽງ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ລັອກ​ດຽວ​ນີ້"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
     <string name="android_system_label" msgid="6577375335728551336">"ລະບົບ Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"​ສ່ວນ​ໂຕ"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"ອັບ​ເດດ​ໂດຍ​ຜູ້​ຄວບ​ຄຸມ​ຂອງ​ທ່ານ​ແລ້ວ"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"ຖືກ​ຜູ້​ຄວບ​ຄຸມ​ຂອງ​ທ່ານ​ລຶບ​ໄປ​ແລ້ວ"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"ເພື່ອ​ຊ່ວຍ​ເພີ່ມ​ອາ​ຍຸ​ແບັດ​ເຕີ​ຣີ, ຕົວ​ປະ​ຢັດ​ໄຟ​ແບັດ​ເຕີ​ຣີ​ຫຼຸດ​ປະ​ສິດ​ທິ​ພາບ​ການ​ເຮັດ​ວຽກ​ຂອງ​ອຸ​ປະ​ກອນ​ຂອງ​ທ່ານ​ລົງ ແລະ​ຈຳ​ກັດ​ການ​ສັ່ນ, ການ​ບໍ​ລິ​ການ​ຫາທີ່ຕັ້ງ, ແລະ​ຂໍ້​ມູນ​ພື້ນ​ຫຼັງ​ເກືອບ​ທັງ​ໝົດ. ອີ​ເມວ, ການ​ສົ່ງ​ຂໍ້​ຄວາມ, ແລະ​ແອັບອື່ນໆ​ທີ່ອາ​ໄສການ​ຊິງ​ຄ໌​ອາດ​ຈະ​ບໍ່​ອັບ​ເດດ ນອກ​ຈາກວ່າ​ທ່ານ​ເປີດ​ມັນ.\n\nຕົວ​ປະ​ຢັດ​ໄຟ​ແບັດ​ເຕີ​ຣີຈະ​ປິດ​ອັດ​ຕະ​ໂນ​ມັດ ເມື່ອ​ອຸ​ປະ​ກອນ​ຂອງ​ທ່ານ​ກຳ​ລັງ​ສາກຢູ່."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"ບລັອກແລ້ວ: ຢ່າສະແດງການແຈ້ງເຕືອນເຫຼົ່ານີ້"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"ຕໍ່າ: ສະແດງຢູ່ສ່ວນລຸ່ມຂອງລາຍການແຈ້ງເຕືອນແບບມີບໍ່ສຽງ"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"ປົກກະຕິ: ສະແດງການແຈ້ງເຕືອນເຫຼົ່ານີ້ແບບບໍ່ມີສຽງ"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"ສູງ: ສະແດງຢູ່ສ່ວນເທິງຂອງລາຍການແຈ້ງເຕືອນ ແລະສົ່ງສຽງດັງ"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"ດ່ວນ: ເດັ້ງຂຶ້ນເທິງຫນ້າຈໍ ແລະສົ່ງສຽງດັງ"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">ເປັນ​ເວ​ລາ %1$d ນາ​ທີ (ຈົນ​ຮອດ <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">​ເປັນ​ເວ​ລາ 1 ນາ​ທີ (ຈົນ​ຮອດ <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 6ee24cf..b148d2c 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -224,8 +224,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Užrakinti dabar"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Saugos režimas"</string>
     <string name="android_system_label" msgid="6577375335728551336">"„Android“ sistema"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Asmeninė"</string>
@@ -1459,6 +1458,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Atnaujino administratorius"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Ištrynė administratorius"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Kad tausotų akumuliatoriaus energiją akumuliatoriaus tausojimo priemonė sumažina įrenginio veikimą ir apriboja vibravimą, vietovės paslaugas bei daugumą foninių duomenų. El. pašto, susirašinėjimo ir kitos programos, kurios veikia sinchronizavimo pagrindu, gali būti neatnaujintos, nebent jas atidarysite.\n\nAkumuliatoriaus tausojimo priemonė automatiškai išjungiama, kai įrenginys įkraunamas."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Užblokuota: niekada nerodyti šių pranešimų"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Maža: tyliai rodyti pranešimų sąrašo apačioje"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Įprasta: tyliai rodyti šiuos pranešimus"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Didelė: rodyti pranešimų sąrašo viršuje ir skambėti"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Skubu: rodyti ekrane ir skambėti"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">%1$d minutę (iki <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="few">%1$d minutes (iki <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 7785965..892402b 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -223,8 +223,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Balss palīgs"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloķēt tūlīt"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"Pārsniedz"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Drošais režīms"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android sistēma"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Personisks"</string>
@@ -1450,6 +1449,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Atjaunināja administrators"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Izdzēsa jūsu administrators"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Lai paildzinātu akumulatora darbību, akumulatora jaudas taupīšanas režīmā tiek samazināta ierīces veiktspēja un tiek ierobežota vibrācija, atrašanās vietu pakalpojumi un lielākā daļa fona datu. E-pasta, ziņojumapmaiņas un cita veida lietotnes, kuru darbības pamatā ir datu sinhronizācija, var netikt atjauninātas, ja tās neatverat.\n\nTiklīdz tiek sākta ierīces uzlāde, akumulatora jaudas taupīšanas režīms automātiski tiek izslēgts."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Bloķēts: nekad nerādīt šos paziņojumus"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Zemu: rādīt paziņojumu saraksta apakšdaļā bez skaņas signāla"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normāli: rādīt šos paziņojumus bez skaņas signāla"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Augstu: rādīt paziņojumu saraksta augšdaļā un ar skaņas signālu"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Steidzami: rādīt ekrānā ar skaņas signālu"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="zero">%1$d minūtes (līdz <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">%1$d minūti (līdz <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index eb90369..9cfa6cf 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -373,7 +373,7 @@
     <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Овозможува апликацијата да го користи инфрацрвениот предавател на телефонот."</string>
     <string name="permlab_setWallpaper" msgid="6627192333373465143">"подеси тапет"</string>
     <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Дозволува апликацијата да го постави системскиот тапет."</string>
-    <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"прилагоди ја големината на твојот тапет"</string>
+    <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"приспособи ја големината на твојот тапет"</string>
     <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Дозволува апликацијата да постави сугестии за големина на системски тапет."</string>
     <string name="permlab_setTimeZone" msgid="2945079801013077340">"подеси временска зона"</string>
     <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Дозволува апликацијата да ја промени часовната зона на таблетот."</string>
@@ -537,7 +537,7 @@
     <item msgid="1735177144948329370">"Факс дома"</item>
     <item msgid="603878674477207394">"Пејџер"</item>
     <item msgid="1650824275177931637">"Други"</item>
-    <item msgid="9192514806975898961">"Прилагоди"</item>
+    <item msgid="9192514806975898961">"Приспособен"</item>
   </string-array>
   <string-array name="emailAddressTypes">
     <item msgid="8073994352956129127">"Дома"</item>
@@ -622,8 +622,8 @@
     <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string>
     <string name="orgTypeWork" msgid="29268870505363872">"Работа"</string>
     <string name="orgTypeOther" msgid="3951781131570124082">"Друго"</string>
-    <string name="orgTypeCustom" msgid="225523415372088322">"Прилагоди"</string>
-    <string name="relationTypeCustom" msgid="3542403679827297300">"Прилагоди"</string>
+    <string name="orgTypeCustom" msgid="225523415372088322">"Приспособен"</string>
+    <string name="relationTypeCustom" msgid="3542403679827297300">"Приспособена"</string>
     <string name="relationTypeAssistant" msgid="6274334825195379076">"Помошник"</string>
     <string name="relationTypeBrother" msgid="8757913506784067713">"Брат"</string>
     <string name="relationTypeChild" msgid="1890746277276881626">"Дете"</string>
@@ -1442,6 +1442,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Ажурирано од администраторот"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Избришано од администраторот"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"За да ви помогне да ја подобрите трајноста на батеријата, штедачот на батеријата ја намалува изведбата на уредот и го ограничува вибрирањето, услугите за локација и повеќето податоци од заднина. Е-поштата, испраќањето пораки и другите апликации кои се потпираат на синхронизација можеби нема да се ажурираат доколку не ги отворите.\n\nШтедачот на батеријата автоматски се исклучува кога уредот се полни."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Блокирано: никогаш не покажувај ги овие известувања"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Ниско: покажувај ги тивко на дното на списокот со известувања"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Нормално: покажувај ги овие известувања тивко"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Високо: покажувај ги на врв на списокот со известувања и дај звук"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Итно: нека се појават на екранот и дај им звук"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">За %1$d минута (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="other">За %1$d минути (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index a83928e..3a3ec41 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"വോയ്‌സ് സഹായം"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ഇപ്പോൾ ലോക്കുചെയ്യുക"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"സുരക്ഷിത മോഡ്"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android സിസ്റ്റം"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"വ്യക്തിഗതം"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"നിങ്ങളുടെ അഡ്‌മിനിസ്‌ട്രേറ്റർ അപ്‌ഡേറ്റുചെയ്‌തു"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"നിങ്ങളുടെ അഡ്‌മിനിസ്‌ട്രേറ്റർ ഇല്ലാതാക്കി"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"ബാറ്ററി ആയുസ്സ് മെച്ചപ്പെടുത്താൻ സഹായിക്കുന്നതിന്, ബാറ്ററി സേവർ നിങ്ങളുടെ ഉപകരണത്തിന്റെ പ്രകടനത്തെ കുറയ്‌ക്കുകയും വൈബ്രേഷനെയും മിക്ക പശ്ചാത്തല വിവരത്തെയും പരിമിതപ്പെടുത്തുകയും ചെയ്യുന്നു. ഇമെയിൽ, സന്ദേശമയയ്‌ക്കൽ, സമന്വയിപ്പിക്കലിനെ ആശ്രയിച്ചുള്ള മറ്റ് അപ്ലിക്കേഷനുകൾ എന്നിവ നിങ്ങൾ തുറക്കുന്നതുവരെ അപ്‌ഡേറ്റുചെയ്യാനിടയില്ല.\n\nനിങ്ങളുടെ ഉപകരണം ചാർജ്ജുചെയ്യുമ്പോൾ ബാറ്ററി സേവർ സ്വയം ഓഫാകും."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"ബ്ലോക്കുചെയ്തു: ഈ അറിയിപ്പുകൾ ഒരിക്കലും കാണിക്കരുത്"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"താഴ്ന്നത്: അറിയിപ്പ് ലിസ്റ്റിന്റെ താഴെ ശബ്ദമുണ്ടാക്കാതെ കാണിക്കുക"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"സാധാരണം: ഈ അറിയിപ്പുകൾ നിശബ്ദമായി കാണിക്കുക"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"ഉയർന്നത്: അറിയിപ്പ് ലിസ്റ്റിന്റെ ഏറ്റവും മുകളിൽ കാണിക്കുക, ശബ്ദമുണ്ടാക്കുക"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"അടിയന്തരം: സ്ക്രീനിൽ ദൃശ്യമാക്കുക, ശബ്ദമുണ്ടാക്കുക"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">%1$d മിനിറ്റ് സമയത്തേക്ക് (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> വരെ)</item>
       <item quantity="one">ഒരു മിനിറ്റ് സമയത്തേക്ക് (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> വരെ)</item>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index a9fb8593..ab2285b 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Дуут туслах"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Одоо түгжих"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Аюулгүй горим"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Андройд систем"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Хувийн"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Танай админ шинэчилсэн"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Таны админ устгасан байна"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Батарей хадгалах функц нь таны төхөөрөмжийн цэнэгийг хадгалахын тулд гүйцэтгэлийг багасгаж, чичрэлтийг бууруулж, байршлын үйлчилгээнүүд болон бусад өгөгдлийн хэмжээг багасгадаг юм. И-мэйл, мессеж болон бусад синхрон хийдэг апликейшнүүд дараа дахин нээгдэх хүртлээ автоматаар шинэчлэлт хийхгүй.\n\nМөн батарей хадгалах функц нь таныг төхөөрөмжөө цэнэглэх үед автоматаар унтрах юм."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Блоклосон: Эдгээр мэдэгдлийг хэзээ ч харуулахгүй"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Бага: Мэдэгдлийг жагсаалтын доод хэсэгт дуугүй харуулах"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Ердийн: Эдгээр мэдэгдлийг дуугүй харуулах"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Өндөр: мэдэгдлийг жагсаалтын эхэнд дуутай харуулах"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Яаралтай: Дэлгэцэнд яаралтай, дуутай гаргах"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other"> %1$d минутын турш ( <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> хүртэл)</item>
       <item quantity="one">нэг минутын турш (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> хүртэл)</item>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index a8896c3..92f114a 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"व्हॉइस सहाय्य"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"आता लॉक करा"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android सिस्‍टम"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"वैयक्तिक"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"आपल्या प्रशासकाद्वारे अद्यतनित केले"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"आपल्या प्रशासकाद्वारे हटविले आहे"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"बॅटरीचे आयुष्य सुधारित करण्‍यात मदत करण्यासाठी, बॅटरी बचतकर्ता आपल्या डिव्हाइसचे कार्यप्रदर्शन कमी करतो आणि कंपन, स्थान सेवा आणि बराच पार्श्वभूमी डेटा मर्यादित करतो. संकालनावर अवलंबून असणारे ईमेल, संदेशन आणि इतर अ‍ॅप्स आपण उघडल्याशिवाय अद्यतनित होऊ शकत नाहीत.\n\nआपले डिव्हाइस चार्ज होत असते तेव्हा बॅटरी बचतकर्ता स्वयंचलितपणे बंद होतो."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"अवरोधित केले: या सूचना कधीही दर्शवू नका"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"कमी: शांतपणे सूचना सूचीच्या तळाशी दर्शवा"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"सामान्य: या सूचना शांतपणे दर्शवा"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"सर्वोच्च: सूचना सूचीच्या शीर्षस्थानी दर्शवा आणि ध्वनी चालू करा"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"त्वरित: स्क्रीनवर डोकावून पहा आणि ध्वनी चालू करा"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">%1$d मिनिटासाठी (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> पर्यंत)</item>
       <item quantity="other">%1$d मिनिटांसाठी (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> पर्यंत)</item>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index cababdd..ab683fcb 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Bantuan Suara"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Kunci sekarang"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mod selamat"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Peribadi"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Dikemas kini oleh pentadbir anda"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Dipadamkan oleh pentadbir anda"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Untuk membantu memperbaik hayat bateri, penjimat bateri mengurangkan prestasi peranti anda dan mengehadkan getaran, perkhidmatan lokasi dan kebanyakan data latar belakang. E-mel, pemesejan dan apl lain yang bergantung kepada penyegerakan mungkin tidak mengemas kini, melainkan anda membuka apl itu.\n\nPenjimat bateri dimatikan secara automatik semasa peranti anda sedang dicas."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Disekat: Jangan sekali-kali tunjukkan pemberitahuan ini"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Rendah: Tunjukkan pada bahagian bawah senarai pemberitahuan secara senyap"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Biasa: Tunjukkan pemberitahuan ini secara senyap"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Tinggi: Tunjukkan pada bahagian atas senarai pemberitahuan dan bunyikan"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Segera: Intai pada skrin dan bunyikan"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">Selama %1$d minit (sehingga <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">Selama satu minit (sehingga <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index 8e61f41..8709c7c 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"အသံ အကူအညီ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ယခု သော့ပိတ်ရန်"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"၉၉၉+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"အန္တရာယ်ကင်းမှု စနစ်(Safe mode)"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android စနစ်"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"ကိုယ်ရေး"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"သင့်စီမံခန့်ခွဲသူမှ အဆင့်မြှင့်ထားပါသည်။"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"သင့် အက်ဒမင်အား ဖျက်ပစ်ရန်"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"ဘက်ထရီသက်တမ်း ကြာရှည်ခံရန်၊ ဘက်ထရီအားထိန်းသည် သင့်ကိရိယာ၏ ဆောင်ရွက်ချက်ကို  လျှော့ပေးပြီး တုန်ခါမှု၊ တည်နေရာဝန်ဆောင်မှုများနှင့်၊ နောက်ခံဒေတာအများစုကို ကန့်သတ်ပေး၏။ စင့်လုပ်ပေးရလေ့ရှိသည့် အီးမေး၊ စာပို့ခြင်းနှင့်၊ အခြားအပလီကေးရှင်းများကို ၎င်းတို့အား သင် ဖွင့်မှသာ အဆင့်မြှင့်မွမ်းမံမည်ဖြစ်၏။ \n\n ကိရိယာအား အားသွင်းနေစဉ် ဘက်ထရီအားထိန်းအား အလိုအလျောက် ပိတ်ထားသည်။"</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"ပိတ်ဆို့ထား- ဤသတိပေးချက်များကို ဘယ်တော့မှ မပြပါနှင့်"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"နိမ့်- တိတ်ဆိတ်စွာ သတိပေးချက်များ၏ စာရင်း အောက်ပိုင်းမှာ ပြပါ"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"\'ပုံမှန်- ဤသတိပေးချက်များကို တိတ်ဆိတ်စွာ ပြပါ"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"မြင့်မား- သတိပေးချက်များ၏ စာရင်းထိပ်မှာ ပြလျက် အသံမြည်ပေးပါ"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"အရေးကြီး- : မျက်နှာပြင်မှာ ပြပေးလျက် အသံမြည်ပေးပါ"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">%1$d မိနစ်တွင် (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>အထိ)</item>
       <item quantity="one">တစ်မိနစ်တွင် (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> အထိ)</item>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index f29a903..c966e38 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Talehjelp"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Lås nå"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Sikkermodus"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android-system"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Personlig"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Oppdatert av administratoren"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Slettet av administratoren"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"For å forlenge batterilevetiden reduserer batterispareren ytelsen til enheten din og begrenser vibrering, posisjonstjenester og mesteparten av bakgrunnsdataene. E-post, sending av meldinger og andre apper som er avhengig av synkronisering, oppdateres kanskje ikke med mindre du åpner dem.\n\nBatterisparing slås av automatisk når enheten lader."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Blokkert: Aldri vis disse varslene"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Lavt: Vis nederst i varsellisten uten lyd"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normalt: Vis disse varslene uten lyd"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Høyt: Vis øverst i varsellisten med lyd"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Haster: Vises fort på skjermen med lyd"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">I %1$d minutter (til <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">I 1 minutt (til <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index a33289f..931c880 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"आवाज सहायता"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"अब बन्द गर्नुहोस्"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"९९९+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string>
     <string name="android_system_label" msgid="6577375335728551336">"एन्ड्रोइड प्रणाली"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"व्यक्तिगत"</string>
@@ -1447,6 +1446,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"तपाईँको प्रशासकद्वारा अद्यावधिक गरिएको"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"तपाईँको प्रशासकद्वारा हटाइएको"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"ब्याट्रीको आयु सुधार्न, ब्याट्री संरक्षकले तपाईँको यन्त्रको कार्यसम्पादन घटाउँछ र भाइब्रेसन, स्थान सेवा र बहुसंख्यक पृष्ठभूमि डेटा सीमित गर्दछ। इमेल, सन्देश, र अन्य अनुप्रयोगहरू जुन सिङ्कमा भर पर्छन् अद्यावधिक नहुन सक्छन् जबसम्म तपाईँ तिनीहरूलाई खोल्नुहुन्न\n\n ब्याट्री संरक्षक स्वत: निस्कृय हुन्छ जब तपाईँको यन्त्र चार्ज हुँदै हुन्छ।"</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"रोकिएको: यी सूचनाहरू कहिल्यै नदेखाउनुहोस्"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"कम: चुपचाप सूचना सूचीको फेदमा देखाउनुहोस्"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"सामान्य: चुपचाप यी सूचनाहरू देखाउनुहोस्"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"उच्च: सूचना सूचीको शीर्षमा देखाउनुहोस् र आवाज निकाल्नुहोस्"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"जरुरी: स्क्रिनमा झलक्क हेर्नुहोस् र आवाज निकाल्नुहोस्"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other"> %1$d मिनेटको लागि (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> सम्म)</item>
       <item quantity="one">एक मिनेटको लागि (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> सम्म)</item>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 53b45b0..ee4f63a 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1440,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Geüpdatet door je beheerder"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Verwijderd door je beheerder"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Accubesparing beperkt de prestaties van je apparaat, de trilstand, locatieservices en de meeste achtergrondgegevens om de gebruiksduur van de accu te verlengen.\n\nAccubesparing wordt automatisch uitgeschakeld terwijl je apparaat wordt opgeladen."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Geblokkeerd: deze meldingen nooit weergeven"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Laag: zonder geluid onder aan de lijst met meldingen weergeven"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normaal: deze meldingen zonder geluid weergeven"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Hoog: boven aan de lijst met meldingen weergeven en geluid laten horen"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Urgent: op het scherm weergeven en geluid laten horen"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">%1$d minuten (tot <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">Eén minuut (tot <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml
index d450bf9..ddc7b73 100644
--- a/core/res/res/values-pa-rIN/strings.xml
+++ b/core/res/res/values-pa-rIN/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ਵੌਇਸ ਅਸਿਸਟ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ਹੁਣ ਲੌਕ ਕਰੋ"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"ਸੁਰੱਖਿਅਤ ਮੋਡ"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"ਨਿੱਜੀ"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਦੁਆਰਾ ਅਪਡੇਟ ਕੀਤਾ ਗਿਆ"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"ਤੁਹਾਡੇ ਪ੍ਰਬੰਧਕ ਵੱਲੋਂ ਮਿਟਾਇਆ ਗਿਆ"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"ਬੈਟਰੀ ਸਮਰੱਥਾ ਨੂੰ ਬਿਹਤਰ ਸਹਾਇਤਾ ਕਰਨ ਲਈ, ਬੈਟਰੀ ਸੇਵਰ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਦਾ ਪ੍ਰਦਰਸ਼ਨ ਘਟਾਉਂਦਾ ਹੈ ਅਤੇ ਵਾਈਬ੍ਰੇਸ਼ਨ, ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਸੇਵਾਵਾਂ ਅਤੇ ਜ਼ਿਆਦਾਤਰ ਪਿਛੋਕੜ ਡਾਟਾ ਨੂੰ ਸੀਮਿਤ ਕਰਦਾ ਹੈ। ਈਮੇਲ, ਮੈਸੇਜਿੰਗ ਅਤੇ ਹੋਰ ਐਪਸ, ਜੋ ਸਿੰਕਿੰਗ ਤੇ ਨਿਰਭਰ ਹਨ, ਉਹ ਉਦੋਂ ਤੱਕ ਅਪਡੇਟ ਨਹੀਂ ਕੀਤੇ ਜਾ ਸਕਦੇ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਉਹਨਾਂ ਨੂੰ ਖੋਲ੍ਹਦੇ ਨਹੀਂ।\n\nਬੈਟਰੀ ਸੇਵਰ ਆਟੋਮੈਟਿਕਲੀ ਬੰਦ ਹੁੰਦਾ ਹੈ ਜਦੋਂ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਚਾਰਜ ਹੋ ਰਹੀ ਹੁੰਦੀ ਹੈ।"</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"ਬਲੌਕ ਕੀਤਾ: ਇਹ ਸੂਚਨਾਵਾਂ ਕਦੇ ਨਾ ਵਿਖਾਓ"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"ਘੱਟ: ਚੁੱਪਚਾਪ ਢੰਗ ਨਾਲ ਸੂਚਨਾ ਸੂਚੀ ਦੇ ਹੇਠਾਂ ਵਿਖਾਓ"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"ਸਧਾਰਨ: ਇਹ ਸੂਚਨਾਵਾਂ ਚੁੱਪਚਾਪ ਢੰਗ ਨਾਲ ਵਿਖਾਓ"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"ਵੱਧ: ਸੂਚਨਾਵਾਂ ਸੂਚੀ ਦੇ ਸਿਖਰ \'ਤੇ ਵਿਖਾਓ ਅਤੇ ਆਵਾਜ਼ ਕਰੋ"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"ਜ਼ਰੂਰੀ: ਸਕਰੀਨ \'ਤੇ ਝਾਤੀ ਮਾਰੋ ਅਤੇ ਆਵਾਜ਼ ਕਰੋ"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">%1$d ਮਿੰਟਾਂ ਤੱਕ (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> ਤੱਕ) </item>
       <item quantity="other">%1$d ਮਿੰਟਾਂ ਤੱਕ (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> ਤੱਕ)</item>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index b7f984d..7430d54 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -224,8 +224,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Asystent głosowy"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Zablokuj teraz"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Tryb awaryjny"</string>
     <string name="android_system_label" msgid="6577375335728551336">"System Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Osobiste"</string>
@@ -1459,6 +1458,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Zaktualizowane przez administratora"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Usunięty przez administratora"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Aby wydłużyć czas pracy baterii, Oszczędzanie baterii ogranicza aktywność urządzenia, w tym wibracje, usługi lokalizacyjne i przetwarzanie większości danych w tle. Poczta, czat i inne synchronizowane aplikacje mogą nie aktualizować swojej zawartości, dopóki ich nie otworzysz.\n\nOszczędzanie baterii wyłącza się automatycznie podczas ładowania urządzenia."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Zablokowana: nigdy nie pokazuj tych powiadomień"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Niska: pokazuj na dole listy powiadomień bez sygnału dźwiękowego"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normalna: pokazuj te powiadomienia bez sygnału dźwiękowego"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Wysoka: pokazuj na początku listy powiadomień i odtwarzaj dźwięk"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Pilna: wyświetlaj na ekranie i odtwarzaj dźwięk"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="few">Przez %1$d minuty (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="many">Przez %1$d minut (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 4464259..f787499 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Ajuda de voz"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear agora"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modo de segurança"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Pessoal"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Atualizado pelo administrador"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Excluído pelo seu administrador"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Para ajudar a melhorar a duração da bateria, o economizador de bateria reduz o desempenho e os limites de vibração do dispositivo, os serviços de localização e a maioria dos dados de segundo plano. E-mail, mensagens e outros aplicativos que dependem de sincronização não podem ser atualizados, a não ser que você os abra.\n\nO economizador de bateria é desligado automaticamente quando o dispositivo está sendo carregado."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Bloqueada: nunca mostrar essas notificações"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Baixa: mostrar na parte inferior da lista de notificações de forma silenciosa"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normal: mostrar essas notificações de forma silenciosa"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Alta: mostrar na parte superior da lista de notificações e emitir som"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Urgente: mostrar parcialmente na tela e emitir som"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">Por %1$d minutos (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="other">Por %1$d minutos (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index af38435..826771e 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Assist. de voz"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear agora"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Pessoal"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Atualizado pelo administrador"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Eliminado pelo administrador"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Para ajudar a melhorar a autonomia da bateria, a poupança de bateria reduz o desempenho do seu dispositivo e limita a vibração, os serviços de localização e a maioria dos dados em segundo plano. O email, as mensagens e outras aplicações que dependem da sincronização não podem ser atualizados exceto se os abrir.\n\nA poupança de bateria desliga-se automaticamente quando o dispositivo está a carregar."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Bloqueado: nunca mostrar estas notificações"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Baixo: mostrar na parte inferior da lista de notificações sem som"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normal: mostrar estas notificações sem som"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Elevado: mostrar na parte superior da lista de notificações com som"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Urgente: mostrar no ecrã com som"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">Durante %1$d minutos (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">Durante um minuto (até às <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 4464259..f787499 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Ajuda de voz"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear agora"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Modo de segurança"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Pessoal"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Atualizado pelo administrador"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Excluído pelo seu administrador"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Para ajudar a melhorar a duração da bateria, o economizador de bateria reduz o desempenho e os limites de vibração do dispositivo, os serviços de localização e a maioria dos dados de segundo plano. E-mail, mensagens e outros aplicativos que dependem de sincronização não podem ser atualizados, a não ser que você os abra.\n\nO economizador de bateria é desligado automaticamente quando o dispositivo está sendo carregado."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Bloqueada: nunca mostrar essas notificações"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Baixa: mostrar na parte inferior da lista de notificações de forma silenciosa"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normal: mostrar essas notificações de forma silenciosa"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Alta: mostrar na parte superior da lista de notificações e emitir som"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Urgente: mostrar parcialmente na tela e emitir som"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">Por %1$d minutos (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="other">Por %1$d minutos (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 7ac92c3..f49d6a1 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -223,8 +223,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Asistent vocal"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Blocați acum"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"˃999"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mod sigur"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistemul Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
@@ -1450,6 +1449,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Actualizat de un administrator"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Șters de administrator"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Pentru a îmbunătăți autonomia bateriei, funcția de economisire a energiei reduce performanțele dispozitivului și limitează vibrațiile, serviciile de localizare și majoritatea datelor de fundal. Este posibil ca e-mailurile, mesageria și alte aplicații care depind de sincronizare să nu se actualizeze dacă nu le deschideți.\n\nFuncția de economisire a energiei se dezactivează automat când dispozitivul se încarcă."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Blocate: aceste notificări nu se afișează niciodată"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Redusă: se afișează în partea de jos a listei cu notificări fără a se emite un sunet"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normală: aceste notificări se afișează fără a se emite un sunet"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Ridicată: se afișează în partea de sus a listei cu notificări și se emite un sunet"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Urgente: se afișează pentru o scurtă durată pe ecran și se emite un sunet"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="few">Timp de %1$d minute (până la <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="other">Timp de %1$d de minute (până la <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index b7ba99f..cee24da 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -224,8 +224,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Аудиоподсказки"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Заблокировать"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Безопасный режим"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Система Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Личные данные"</string>
@@ -243,7 +242,7 @@
     <string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"запись аудио"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"Камера"</string>
-    <string name="permgroupdesc_camera" msgid="3250611594678347720">"фото- и видеосъемка"</string>
+    <string name="permgroupdesc_camera" msgid="3250611594678347720">"снимать фото и видео"</string>
     <string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"осуществление телефонных звонков и управление ими"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"Нательные датчики"</string>
@@ -1459,6 +1458,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Обновлено администратором"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Удалено администратором"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Чтобы продлить время работы устройства от батареи, в режиме энергосбережения снижается производительность, а также ограничивается использование вибрации, геолокации и фоновой передачи данных. Данные, требующие синхронизации, могут обновляться только когда вы откроете приложение.\n\nРежим энергосбережения автоматически отключается во время зарядки устройства."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Заблокировано: не показывать эти уведомления"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Низкая: показывать без звука в конце списка уведомлений"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Обычная: показывать уведомления без звука"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Высокая: показывать со звуком в начале списка уведомлений"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Срочно: показывать со звуковым сигналом поверх всех окон"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">%1$d минута (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="few">%1$d минуты (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 4e265177..c8a45eb1 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"හඬ සහායක"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"දැන් අගුළු දමන්න"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"ආරක්‍ෂිත ආකාරය"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android පද්ධතිය"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"පෞද්ගලික"</string>
@@ -1443,6 +1442,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"ඔබගේ පරිපාලක විසින් යාවත්කාලීන කරන ලදී"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"ඔබගේ පරිපාලක විසින් මකන ලද"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"බැටරි ආයු කාලය වැඩිදියුණු කිරීමට උදවු කිරීමට, බැටරි සුරැකුම ඔබේ උපාංගයේ ක්‍රියාකාරීත්වය අඩුකරන අතර කම්පනය, පිහිටීම් සේවා, සහ බොහෝමයක් පසුබිම් දත්ත සීමා කරයි. ඔබ ඒවා විවෘත නොකරන්නේ නම් මිස ඊමේල්, පණිවිඩකරණය, සහ සමමුහුර්ත කිරීම මත රඳා පවතින වෙනත් යෙදුම් යාවත්කාලීන නොවිය හැකිය.\n\nඔබේ උපාංගය ආරෝපණය වන විට බැටරි සුරැකුම ස්වයංක්‍රියව අක්‍රිය වේ."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"අවහිර කළ: මෙම දැනුම්දීම් කිසිදා නොපෙන්වන්න"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"අඩු: දැනුම්දීම් ලැයිස්තුවෙහි පහළින්ම නිශ්ශබ්දව පෙන්වන්න"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"සාමාන්‍ය: නිශ්ශබ්දව මෙම දැනුම්දීම් පෙන්වන්න"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"වැඩි: දැනුම්දීම් ලැයිස්තුවෙහි ඉහළින්ම පෙන්වන්න සහ ශබ්ද කරන්න"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"හදිසි: තිරයට පැමිණ ශබ්ද කරන්න"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">මිනිත්තු %1$d ක් සඳහා (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> තෙක්)</item>
       <item quantity="other">මිනිත්තු %1$d ක් සඳහා (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> තෙක්)</item>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index ba5465e..242a844 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -224,8 +224,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Hlasový asistent"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Uzamknúť"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Núdzový režim"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Systém Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Osobné"</string>
@@ -1459,6 +1458,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Aktualizované správcom"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Odstránený správcom"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"S cieľom predĺžiť výdrž batérie zníži šetrič batérie výkonnosť zariadenia a obmedzí vibrácie, služby určovania polohy a dátové prenosy na pozadí. Pošta, čet a ďalšie aplikácie, ktoré sa spoliehajú na synchronizáciu, sa možno nebudú aktualizovať, dokiaľ ich neotvoríte.\n\nPri nabíjaní zariadenia sa šetrič batérie automaticky vypne."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Blokované: Tieto upozornenia nikdy nezobrazovať"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Nízke: Zobrazovať v dolnej časti zoznamu upozornení bez zvukového signálu"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normálne: Tieto upozornenia zobrazovať bez zvukového signálu"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Vysoké: Zobrazovať v hornej časti zoznamu upozornení so zvukovým signálom"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Neodkladné: Zobraziť cez obrazovku so zvukovým signálom"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="few">%1$d minúty (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="many">%1$d minúty (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 04b7fc7..3f6769c 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -224,8 +224,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Glas. pomočnik"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Zakleni zdaj"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999 +"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Varni način"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Osebno"</string>
@@ -1459,6 +1458,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Posodobil skrbnik"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Izbrisal skrbnik"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Varčevanje z energijo akumulatorja podaljša čas njegovega delovanja tako, da zmanjša zmogljivost delovanja naprave in omeji vibriranje, lokacijske storitve ter prenos večine podatkov v ozadju. Aplikacije za e-pošto, sporočanje in drugo, ki uporabljajo sinhroniziranje, se morda ne posodabljajo, razen če jih odprete.\n\nVarčevanje z energijo akumulatorja se samodejno izklopi med polnjenjem akumulatorja naprave."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Blokirano: nikoli ne prikaži teh obvestil"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Manj pomembno: prikaži na dnu seznama obvestil brez zvoka"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Običajno: prikaži ta obvestila brez zvoka"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Pomembno: prikaži na vrhu seznama obvestil in predvajaj zvok"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Nujno: za hip pokaži predogled na zaslonu in predvajaj zvok"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">%d minuto (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="two">%d minuti (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml
index b8ca565..2653c71 100644
--- a/core/res/res/values-sq-rAL/strings.xml
+++ b/core/res/res/values-sq-rAL/strings.xml
@@ -1440,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Përditësuar nga administratori"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"U fshi nga administratori yt"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Për të përmirësuar jetëgjatësinë e baterisë, opsioni i kursimit të baterisë ul rendimentin e pajisjes tënde si dhe kufizon dridhjet dhe shumicën e të dhënave në sfond. Mail-i, mesazhet dhe aplikacionet e tjera që sinkronizohen automatikisht mund të mos përditësohen pa i hapur.\n\nKursimi i baterisë çaktivizohet automatikisht kur pajisja vihet në ngarkim."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Të bllokuara: Mos i shfaq asnjëherë këto njoftime"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Të ulëta: Shfaqi në heshtje në fund të listës së njoftimeve"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normale: Shfaqi këto njoftime në heshtje"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Të larta: Shfaqi në krye të listës së njoftimeve dhe lësho tingull"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Urgjente: Shfaq një vështrim të shpejtë në ekran dhe lësho tingull"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">Për %1$d minuta (deri në <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">Për një minutë (deri në <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 4118c63..069d717 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -223,8 +223,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Гласовна помоћ"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Закључај одмах"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Безбедни режим"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android систем"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Лично"</string>
@@ -1450,6 +1449,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Ажурирао је администратор"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Избрисао је ваш адмиистратор"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Да би продужила време трајања батерије, уштеда батерије смањује перформансе уређаја и ограничава вибрацију, услуге локације и већину позадинских података. Имејл, размена порука и друге апликације које се ослањају на синхронизацију можда неће да се ажурирају ако их не отворите.\n\nУштеда батерије се аутоматски искључује када се уређај пуни."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Блокирана: Ова обавештења се никада не приказују"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Ниска: Приказују се у дну листе обавештења без звука"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Уобичајена: Ова обавештења се приказују без звука"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Висока: Приказују се у врху листе обавештења и активира се звучни сигнал"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Хитна: Накратко се приказују на екрану и активира се звучни сигнал"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">%1$d минут (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="few">%1$d минута (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 40141de..748257a 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Lås nu"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Säkert läge"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android-system"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Personligt"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Uppdaterat av administratören"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Paketet har raderats av administratören"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"I batterisparläget reduceras enhetens prestanda så att batteriet ska räcka längre och vibration, platstjänster samt den mesta användningen av bakgrundsdata begränsas. Det kan hända att appar för e-post, sms och annat som kräver synkronisering inte uppdateras förrän du öppnar dem.\n\nBatterisparläget inaktiveras automatiskt när enheten laddas."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Blockerad: Visa aldrig dessa aviseringar"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Låg: Visa längst ned i aviseringslistan – utan ljud"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normal: Visa aviseringarna – utan ljud"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Hög: Visa högst upp i aviseringslistan – med ljud"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Brådskande: Visa på skärmen – med ljud"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">I %1$d minuter (till kl. <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">I en minut (till kl. <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 196d5dc..cdb86ae 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -224,8 +224,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Usaidizi wa Sauti"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Funga sasa"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mtindo salama"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Mfumo wa Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Binafsi"</string>
@@ -1443,6 +1442,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Kimesasiswa na msimamizi wako"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Kilifutwa na msimamizi wako"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Kusaidia kuboresha muda wa matumizi ya betri, inayookoa betri hupunguza utendaji wa kifaa chako na kupunguza mtetemo, huduma za utambuzi wa mahali, na data nyingi ya chini chini. Barua pepe, ujumbe na programu nyingine zinazotege,ea usawazishaji huenda zisisasishwe usipozifungua.\n\nInayookoa betri hujizima kiotomatiki kifaa chako kinapokuwa kinachaji."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Imezuiwa: Usionyeshe arifa hizi kamwe"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Chini: Onyesha katika sehemu ya chini ya orodha ya arifa bila kutoa sauti"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Kawaida: Onyesha arifa hizi bila sauti"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Juu: Onyesha katika sehemu ya juu ya orodha ya arifa na itoe sauti"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Muhimu: Weka onyesho la kuchungulia kwenye skrini na itoe sauti"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">Kwa dakika %1$d (hadi <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">Kwa dakika moja (hadi <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index 1113776..245f1ca 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"குரல் உதவி"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"இப்போது பூட்டு"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"பாதுகாப்பு பயன்முறை"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android அமைப்பு"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"தனிப்பட்ட"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"உங்கள் நிர்வாகி புதுப்பித்துள்ளார்"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"நிர்வாகி நீக்கிவிட்டார்"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"பேட்டரி ஆயுளை மேம்படுத்த, பேட்டரி சேமிப்பான் உங்கள் சாதனத்தின் செயல்திறனைக் குறைத்து, அதிர்வு, இடச் சேவைகள் மற்றும் பெரும்பாலான பின்புலத் தரவு போன்றவற்றைக் கட்டுப்படுத்துகிறது. ஒத்திசைவைச் சார்ந்துள்ள மின்னஞ்சல், செய்தியிடல் மற்றும் பிற பயன்பாடுகள் திறக்கும்வரை, அவை புதுப்பிக்கப்படாமல் இருக்கலாம்.\n\nஉங்கள் ஃபோன் சார்ஜ் செய்யப்படும்போது, பேட்டரி சேமிப்பான் தானாகவே முடங்கும்."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"தடுக்கப்பட்டது: இந்த அறிவிப்புகளை ஒருபோதும் காட்டாது"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"குறைவு: ஒலியின்றி அறிவிப்புப் பட்டியலின் கீழே காட்டும்"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"இயல்பு: ஒலியின்றி இந்த அறிவிப்புகளைக் காட்டும்"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"அதிகம்: அறிவிப்புகள் பட்டியலின் மேல் பகுதியில் ஒலியுடன் காட்டும்"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"அவசரம்: ஒலியுடன் திரையில் தோன்றும்"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">%1$d நிமிடங்களுக்கு (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> வரை)</item>
       <item quantity="one">ஒரு நிமிடத்திற்கு (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> வரை)</item>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index c563e7c..1b63c2f 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"వాయిస్ సహాయకం"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ఇప్పుడు లాక్ చేయండి"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"సురక్షిత మోడ్"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android సిస్టమ్"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"వ్యక్తిగతం"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"మీ నిర్వాహకుడు నవీకరించారు"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"మీ నిర్వాహకులు తొలగించారు"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"బ్యాటరీ జీవితకాలాన్ని మెరుగుపరచడంలో సహాయపడటానికి, బ్యాటరీ సేవర్ మీ పరికరం పనితీరును తగ్గిస్తుంది మరియు వైబ్రేషన్‌ను, స్థాన సేవలను మరియు ఎక్కువ నేపథ్య డేటాను పరిమితం చేస్తుంది. ఇమెయిల్, మెసేజింగ్ మరియు సమకాలీకరణపై ఆధారపడే ఇతర అనువర్తనాలు మీరు వాటిని తెరిస్తే మినహా నవీకరించబడవు.\n\nమీ పరికరం ఛార్జ్ అవుతున్నప్పుడు బ్యాటరీ సేవర్ స్వయంచాలకంగా ఆఫ్ అవుతుంది."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"బ్లాక్ చేయబడింది: ఈ నోటిఫికేషన్‌లను ఎప్పుడూ చూపదు"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"తక్కువ: నోటిఫికేషన్‌ల జాబితా దిగువ భాగంలో శబ్దం లేకుండా చూపుతుంది"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"సాధారణం: ఈ నోటిఫికేషన్‌లను శబ్దం లేకుండా చూపుతుంది"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"అధికం: నోటిఫికేషన్‌ల జాబితా ఎగువ భాగంలో శబ్దంతో చూపుతుంది"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"అత్యవసరం: స్క్రీన్‌పై శీఘ్రంగా శబ్దంతో చూపుతుంది"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">%1$d నిమిషాల పాటు (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> వరకు)</item>
       <item quantity="one">ఒక నిమిషం పాటు (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> వరకు)</item>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 0080f51..57b9598 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"ตัวช่วยเสียง"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ล็อกเลย"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"โหมดปลอดภัย"</string>
     <string name="android_system_label" msgid="6577375335728551336">"ระบบ Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"ส่วนตัว"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"อัปเดตโดยผู้ดูแลระบบ"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"ลบโดยผู้ดูแลระบบของคุณ"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"เพื่อช่วยปรับปรุงอายุการใช้งานแบตเตอรี่ โหมดประหยัดแบตเตอรี่จะลดการทำงานของอุปกรณ์และจำกัดการสั่น บริการตำแหน่ง และข้อมูลแบ็กกราวด์ส่วนใหญ่ สำหรับอีเมล การรับส่งข้อความ และแอปอื่นๆ ที่ใช้การซิงค์จะไม่อัปเดตหากคุณไม่เปิดขึ้นมา\n\nโหมดประหยัดแบตเตอรี่จะปิดโดยอัตโนมัติขณะชาร์จอุปกรณ์"</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"บล็อก: อย่าแสดงการแจ้งเตือนเหล่านี้"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"ต่ำ: แสดงที่ด้านล่างของรายการแจ้งเตือนโดยไม่ส่งเสียง"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"ปกติ: แสดงการแจ้งเตือนเหล่านี้โดยไม่ส่งเสียง"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"สูง: แสดงที่ด้านบนของรายการแจ้งเตือนและส่งเสียง"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"ด่วน: แสดงบนหน้าจอในช่วงเวลาสั้นๆ และส่งเสียง"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">ระยะเวลา %1$d นาที (จนถึงเวลา <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">ระยะเวลา 1 นาที (จนถึงเวลา <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 4f907c1..8cca676 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"I-lock ngayon"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Personal"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Na-update ng iyong administrator"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Na-delete ng iyong administrator"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Upang matulungang pagbutihin ang tagal ng baterya, binabawasan ng pangtipid ng baterya ang pagganap ng iyong device at nililimitahan ang pag-vibrate, mga serbisyo ng lokasyon at karamihan sa data ng background. Maaaring hindi mag-update ang email, pagmemensahe at iba pang mga app na umaasa sa pagsi-sync maliban kung buksan mo ang mga iyon.\n\nAwtomatikong nag-o-off ang pangtipid ng baterya kapag nagcha-charge ang iyong device."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Naka-block: Huwag kailanman ipakita ang mga notification na ito"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Mababa: Tahimik na ipakita sa ibaba ng listahan ng mga notification"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normal: Tahimik na ipakita ang mga notification na ito"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Mataas: Ipakita sa taas ng listahan ng mga notification at mag-play ng tunog"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Agaran: Ipasilip sa screen at mag-play ng tunog"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">Sa loob ng %1$d minuto (hanggang <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="other">Sa loob ng %1$d na minuto (hanggang <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 06f8c75..60eee12 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Sesli Yardım"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Şimdi kilitle"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Güvenli mod"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android Sistemi"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Kişisel"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Yöneticiniz tarafından güncellendi"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Yöneticiniz tarafından silindi"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Pil tasarrufu özelliği, pil ömrünü iyileştirmeye yardımcı olmak için cihazın performansını düşürür, titreşimi, konum hizmetlerini ve arka plan verilerinin çoğunu sınırlar. Senkronizasyona dayalı olarak çalışan e-posta, mesajlaşma uygulamaları ve diğer uygulamalar, bunları açmadığınız sürece güncellenmeyebilir.\n\nCihazınız şarj olurken pil tasarrufu otomatik olarak kapatılır."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Engellendi: Bu bildirimleri hiçbir zaman gösterme"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Düşük: Bildirim listesinin altında sessizce göster"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Normal: Bu bildirimleri sessizce göster"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Yüksek: Bildirim listesinin üstünde göster ve ses çıkar"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Acil: Ekrana getir ve ses çıkar"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">%1$d dakika için (şu saate kadar: <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">Bir dakika için (şu saate kadar: <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 721f24d..adf6234 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1458,6 +1458,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Оновлено адміністратором"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Видалив адміністратор"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Щоб подовжити час роботи акумулятора, функція заощадження заряду акумулятора знижує продуктивність пристрою, а також обмежує вібрацію, функції служб локації та передавання більшості фонових даних. Електронна пошта, чати й інші додатки, які синхронізуються, можуть не оновлюватися, доки ви їх не відкриєте.\n\nФункція заощадження заряду акумулятора автоматично вимикається під час заряджання пристрою."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Заблоковано: не показувати ці сповіщення"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Низький пріоритет: показувати ці сповіщення внизу списку без звукового сигналу"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Стандартний пріоритет: показувати ці сповіщення без звукового сигналу"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Високий пріоритет: показувати ці сповіщення вгорі списку зі звуковим сигналом"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Терміново: показувати ці сповіщення на екрані зі звуковим сигналом"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">%1$d хвилину (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="few">%1$d хвилини (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index e31fa57..54af31e 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"ابھی مقفل کریں"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"‎999+‎"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"حفاظتی وضع"</string>
     <string name="android_system_label" msgid="6577375335728551336">"‏Android سسٹم"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"ذاتی"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"آپ کے منتظم نے اپ ڈيٹ کر دیا"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"آپ کے منتظم کی جانب سے حذف کر دیا گیا"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"بیٹری کی میعاد بہتر کرنے میں مدد کرنے کیلئے، بیٹری سیور آپ کے آلہ کی کارکردگی کم کر دیتی ہے اور وائبریشن، مقام کی سروسز اور پس منظر کا بیشتر ڈیٹا محدود کر دیتی ہے۔ ای میل، پیغام رسانی اور مطابقت پذیری پر منحصر دیگر ایپس ممکن ہے اس وقت تک اپ ڈیٹ نہ ہوں جب تک آپ انہیں نہ کھولیں۔\n\nآپ کا آلہ چارج ہوتے وقت بیٹری سیور خود بخود آف ہو جاتی ہے۔"</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"مسدود کردہ: یہ اطلاعات کبھی مت دکھائیں"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"پست: اطلاعات کی فہرست کے نیچے خاموشی سے دکھائیں"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"عام: خاموشی سے یہ اطلاعات دکھائیں"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"اعلی: اطلاعات کی فہرست پر سب سے اوپر دکھائیں اور آواز چلائیں"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"ارجنٹ: اسکرین پر دکھائیں اور آواز چلائیں"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">‏%1$d منٹ کیلئے (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> تک)</item>
       <item quantity="one">ایک منٹ کیلئے (تک <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index 0489638..c4701b6 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Ovozli yordam"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Qulflash"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Xavfsiz usul"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android tizimi"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Shaxsiy"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Administratoringiz tomonidan yangilandi"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Administratoringiz tomonidan o‘chirilgan"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Batareya quvvatini uzoqroq vaqtga yetkazish uchun quvvat tejash funksiyasi qurilmangiz unumdorligini kamaytiradi hamda uning tebranishi va orqa fonda internetdan foydalanishini cheklaydi. Sinxronlanishni talab qiladigan e-pochta, xabar almashinuv va boshqa ilovalar esa qachonki ularni ishga tushirganingizda yangilanadi.\n\nQurilma quvvat olayotganda quvvat tejash funksiyasi avtomatik tarzda o‘chadi."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Bloklangan: bildirishnomalar hech qachon ko‘rsatilmasin"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Past: bildirishnomalar ro‘yxatining pastida ovozsiz ko‘rsatilsin"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Oddiy: bildirishnomalar ovozsiz ko‘rsatilsin"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Yuqori: bildirishnomalar ro‘yxatining yuqorisida ovoz bilan ko‘rsatilsin"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Shoshilinch: barcha oynalar ustida signal ovozi bilan ko‘rsatilsin"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">%1$d daqiqa (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> gacha)</item>
       <item quantity="one">Bir daqiqa (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> gacha)</item>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index ccd1345..336f10a 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"Trợ lý thoại"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"Khóa ngay"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"Chế độ an toàn"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Hệ thống Android"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"Cá nhân"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Được cập nhật bởi quản trị viên của bạn"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Đã bị xóa bởi quản trị viên của bạn"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Để giúp tăng tuổi thọ pin, trình tiết kiệm pin sẽ giảm hiệu suất thiết bị của bạn và hạn chế rung, dịch vụ vị trí và hầu hết dữ liệu nền. Email, nhắn tin và các ứng dụng khác dựa trên đồng bộ hóa có thể không cập nhật nếu bạn không mở chúng.\n\nTrình tiết kiệm pin tự động tắt khi thiết bị của bạn đang sạc."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Đã chặn: Không bao giờ hiển thị các thông báo này"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Thấp: Hiển thị im lặng ở cuối danh sách thông báo"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Bình thường: Hiển thị im lặng các thông báo này"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Cao: Hiển thị ở đầu danh sách thông báo và phát ra âm thanh"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Khẩn cấp: Hiển thị trên màn hình và phát ra âm thanh"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">Trong %1$d phút (cho đến <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">Trong một phút (cho đến <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 1afede0..d54eb1e 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"语音助理"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"立即锁定"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g> 条)"</string>
     <string name="safeMode" msgid="2788228061547930246">"安全模式"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android 系统"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"个人"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"由您单位的管理员更新"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"已被管理员删除"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"为了延长电池的续航时间,节电助手会降低设备的性能,并限制振动、位置信息服务和大部分后台流量。对于电子邮件、聊天工具等依赖于同步功能的应用,可能要打开这类应用时才能收到新信息。\n\n节电助手会在设备充电时自动关闭。"</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"屏蔽:一律不显示这些通知"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"低:在通知列表底部显示,不发出提示音"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"一般:显示这些通知,但不发出提示音"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"高:在通知列表顶部显示,并发出提示音"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"紧急:在屏幕上持续显示,并发出提示音"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">%1$d 分钟(到<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">1 分钟(到<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 84c85bf..a583e37 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"語音助手"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"立即鎖定"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"安全模式"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android 系統"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"個人"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"已由您的管理員更新"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"已由管理員刪除"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"節約電池用量模式有助於延長電池壽命,但這會降低裝置效能,並限制震動、定位服務及大部分背景數據傳輸。除非您啟用,否則電郵、短訊及其他需要使用同步功能的應用程式均不會更新。\n\n當裝置充電時,節約電池用量模式會自動關閉。"</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"已封鎖:永不顯示這些通知"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"低:以靜音方式顯示在通知清單底部"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"一般:以靜音方式顯示這些通知"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"高:顯示在通知清單頂部並發出音效"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"緊急:不時於螢幕出現並發出音效"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">需時 %1$d 分鐘 (完成時間:<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">需時 1 分鐘 (完成時間:<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index b45fe75..0d360493 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -222,8 +222,7 @@
     <string name="global_action_voice_assist" msgid="7751191495200504480">"語音小幫手"</string>
     <string name="global_action_lockdown" msgid="8751542514724332873">"立即鎖定"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"超過 999"</string>
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
     <string name="safeMode" msgid="2788228061547930246">"安全模式"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Android 系統"</string>
     <string name="user_owner_label" msgid="2804351898001038951">"個人"</string>
@@ -1441,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"由您的管理員更新"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"已遭管理員刪除"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"節約耗電量模式會透過降低裝置效能、震動限制、定位服務限制和大多數背景資料運作限制等方式,延長電池續航力。此外,如果未開啟電子郵件、簡訊和其他需要使用同步功能的應用程式,系統將不會自動更新這些應用程式。\n\n當您為裝置充電時,節約耗電量模式會自動關閉。"</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"封鎖:一律不顯示這些通知"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"低:顯示在通知清單底部且不發出任何音效"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"一般:顯示這些通知且不發出任何音效"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"高:顯示在通知清單頂端並發出音效"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"緊急:持續顯示在螢幕上並發出音效"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="other">持續 %1$d 分鐘 (結束時間:<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="one">持續 1 分鐘 (結束時間:<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index c2159d7..ac88851 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1440,6 +1440,11 @@
     <string name="package_updated_device_owner" msgid="8856631322440187071">"Ibuyekezwe ngumqondisi wakho"</string>
     <string name="package_deleted_device_owner" msgid="7650577387493101353">"Isuswe ngumlawuli wakho"</string>
     <string name="battery_saver_description" msgid="1960431123816253034">"Ukusiza ukuthuthukisa impilo yebhethri, isilondoloze sebhethri sehlisa ukusebenza kwedivayisi yakho futhi sikhawulele ukudlidliza, amasevisi wendawo, nedatha eningi yangasemuva. I-imeyili, imilayezo, nezinye izinhlelo zokusebenza ezincike ekuvumelaniseni zingahle zingabuyekezwa ngaphandle kokuthi uzivule.\n\nIsilondolozi sebhethri siyavaleka ngokuzenzakalelayo uma idivayisi yakho ishaja."</string>
+    <string name="notification_importance_blocked" msgid="7118826900767047125">"Okuvinjiwe: Ungalokothi ubonise lezi zaziso"</string>
+    <string name="notification_importance_low" msgid="6447640449918427187">"Okuphansi: Bonisa ngokuthulile ngaphansi kohlu lwesaziso"</string>
+    <string name="notification_importance_default" msgid="7991157697609575271">"Okujwayelekile: Bonisa ngokuthulile lezi zaziso"</string>
+    <string name="notification_importance_high" msgid="3152238637737215654">"Okuphezulu: Bonisa ngaphezulu kohlu lwezaziso uphinde wenze umsindo"</string>
+    <string name="notification_importance_max" msgid="1153693080467904474">"Okuphuthumayo: Bheka kusikrini uphinde wenze umsindo"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
       <item quantity="one">Okwamaminithi angu-%1$d (kuze kube ngo-<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="other">Okwamaminithi angu-%1$d (kuze kube ngo-<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 34a66d0..786554c 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3042,7 +3042,8 @@
         <attr name="imeSubtypeLocale" format="string" />
         <!-- The mode of the subtype. This string can be a mode (e.g. voice, keyboard...) and this
              string will be passed to the IME when the framework calls the IME with the
-             subtype.  -->
+             subtype.  {@link android.view.inputmethod.InputMethodSubtype#getLocale()} returns the
+             value specified in this attribute.  -->
         <attr name="imeSubtypeMode" format="string" />
         <!-- Set true if the subtype is auxiliary.  An auxiliary subtype won't be shown in the
              input method selection list in the settings app.
@@ -3067,6 +3068,9 @@
              this subtype. This is important because many password fields only allow
              ASCII-characters. -->
         <attr name="isAsciiCapable" format="boolean" />
+        <!-- The BCP-47 Language Tag of the subtype.  This replaces
+        {@link android.R.styleable#InputMethod_Subtype_imeSubtypeLocale}.  -->
+        <attr name="languageTag" format="string" />
     </declare-styleable>
 
     <!-- Use <code>spell-checker</code> as the root tag of the XML resource that
@@ -3090,11 +3094,22 @@
         <attr name="label" />
         <!-- The locale of the subtype. This string should be a locale (e.g. en_US, fr_FR...)
              This is also used by the framework to know the supported locales
-             of the spell checker.  -->
+             of the spell checker. {@link android.view.textservice.SpellCheckerSubtype#getLocale()}
+             returns the value specified in this attribute.  -->
         <attr name="subtypeLocale" format="string" />
         <!-- The extra value of the subtype. This string can be any string and will be passed to
              the SpellChecker.  -->
         <attr name="subtypeExtraValue" format="string" />
+        <!-- The unique id for the subtype. The text service (spell checker) framework keeps track
+             of enabled subtypes by ID. When the spell checker package gets upgraded, enabled IDs
+             will stay enabled even if other attributes are different. If the ID is unspecified or
+             or explicitly specified to 0 in XML resources,
+             {@code Arrays.hashCode(new Object[] {subtypeLocale, extraValue}) will be used instead.
+              -->
+        <attr name="subtypeId" />
+        <!-- The BCP-47 Language Tag of the subtype.  This replaces
+        {@link android.R.styleable#SpellChecker_Subtype_subtypeLocale}.  -->
+        <attr name="languageTag" />
     </declare-styleable>
 
     <!-- Use <code>accessibility-service</code> as the root tag of the XML resource that
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index af8ff2e..7711825 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -130,8 +130,8 @@
     <drawable name="notification_template_divider">#29000000</drawable>
     <drawable name="notification_template_divider_media">#29ffffff</drawable>
 
-    <color name="notification_icon_default_color">#ff616161</color>
-    <color name="notification_action_color_filter">@color/secondary_text_material_light</color>
+    <color name="notification_default_color">#757575</color> <!-- Gray 600 -->
+    <color name="notification_icon_default_color">@color/notification_default_color</color>
 
     <color name="notification_progress_background_color">@color/secondary_text_material_light</color>
 
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index decb1ef..97c0e07 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -673,6 +673,10 @@
          closed.  The default is 0. -->
     <integer name="config_lidNavigationAccessibility">0</integer>
 
+    <!-- Indicate whether closing the lid causes the lockscreen to appear.
+         The default is false. -->
+    <bool name="config_lidControlsScreenLock">false</bool>
+
     <!-- Indicate whether closing the lid causes the device to go to sleep and opening
          it causes the device to wake up.
          The default is false. -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index b6b2e20..addeb05 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2683,6 +2683,7 @@
     <public type="attr" name="encryptionAware" />
     <public type="attr" name="preferenceFragmentStyle" />
     <public type="attr" name="canControlMagnification" />
+    <public type="attr" name="languageTag" />
 
     <public type="style" name="Theme.Material.DayNight" />
     <public type="style" name="Theme.Material.DayNight.DarkActionBar" />
diff --git a/core/res/res/values/styles_holo.xml b/core/res/res/values/styles_holo.xml
index 841afd8..3cd60df 100644
--- a/core/res/res/values/styles_holo.xml
+++ b/core/res/res/values/styles_holo.xml
@@ -1176,7 +1176,7 @@
 
     <style name="Widget.Holo.Light.FastScroll" parent="Widget.Holo.FastScroll" />
 
-    <style name="Widget.Holo.SuggestionItem" parent="@android:attr/textAppearanceMedium">
+    <style name="Widget.Holo.SuggestionItem" parent="TextAppearance.Holo.Medium">
         <item name="background">@color/white</item>
         <item name="drawablePadding">8dip</item>
         <item name="ellipsize">marquee</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 71a64cf..7470331 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -16,10 +16,6 @@
 */
 -->
 <resources>
-  <!-- We don't want to publish private symbols in android.R as part of the
-       SDK.  Instead, put them here. -->
-  <private-symbols package="com.android.internal" />
-
   <!-- Private symbols that we need to reference from framework code.  See
        frameworks/base/core/res/MakeJavaSymbols.sed for how to easily generate
        this.
@@ -198,7 +194,6 @@
   <java-symbol type="id" name="inbox_text5" />
   <java-symbol type="id" name="inbox_text6" />
   <java-symbol type="id" name="status_bar_latest_event_content" />
-  <java-symbol type="id" name="action_divider" />
   <java-symbol type="id" name="notification_main_column" />
   <java-symbol type="id" name="sms_short_code_confirm_message" />
   <java-symbol type="id" name="sms_short_code_detail_layout" />
@@ -1480,6 +1475,7 @@
   <java-symbol type="bool" name="config_enableLockScreenRotation" />
   <java-symbol type="bool" name="config_enableLockScreenTranslucentDecor" />
   <java-symbol type="bool" name="config_enableTranslucentDecor" />
+  <java-symbol type="bool" name="config_lidControlsScreenLock" />
   <java-symbol type="bool" name="config_lidControlsSleep" />
   <java-symbol type="bool" name="config_lockDayNightMode" />
   <java-symbol type="bool" name="config_lockUiMode" />
@@ -1878,7 +1874,6 @@
   <java-symbol type="layout" name="notification_template_material_big_text" />
   <java-symbol type="layout" name="notification_template_header" />
   <java-symbol type="layout" name="notification_material_media_action" />
-  <java-symbol type="color" name="notification_action_color_filter" />
   <java-symbol type="color" name="notification_icon_default_color" />
   <java-symbol type="color" name="notification_progress_background_color" />
   <java-symbol type="id" name="media_actions" />
@@ -1958,10 +1953,12 @@
   <java-symbol type="bool" name="config_built_in_sip_phone" />
   <java-symbol type="id" name="maximize_window" />
   <java-symbol type="id" name="close_window" />
-  <java-symbol type="id" name="client_decor_placeholder" />
-  <java-symbol type="layout" name="decor_caption_light" />
-  <java-symbol type="layout" name="decor_caption_dark" />
+  <java-symbol type="layout" name="decor_caption" />
   <java-symbol type="drawable" name="decor_caption_title_focused" />
+  <java-symbol type="drawable" name="decor_close_button_dark" />
+  <java-symbol type="drawable" name="decor_close_button_light" />
+  <java-symbol type="drawable" name="decor_maximize_button_dark" />
+  <java-symbol type="drawable" name="decor_maximize_button_light" />
 
   <!-- From TelephonyProvider -->
   <java-symbol type="xml" name="apns" />
@@ -2268,6 +2265,7 @@
 
   <!-- Floating toolbar -->
   <java-symbol type="id" name="floating_toolbar_menu_item_image_button" />
+  <java-symbol type="id" name="overflow" />
   <java-symbol type="layout" name="floating_popup_container" />
   <java-symbol type="layout" name="floating_popup_menu_button" />
   <java-symbol type="layout" name="floating_popup_open_overflow_button" />
@@ -2370,7 +2368,10 @@
   <java-symbol type="id" name="sub_text_divider" />
   <java-symbol type="id" name="content_info_divider" />
   <java-symbol type="id" name="text_line_1" />
-  <java-symbol type="drawable" name="ic_arrow_up_14dp" />
+  <java-symbol type="drawable" name="ic_expand_notification" />
+  <java-symbol type="drawable" name="ic_collapse_notification" />
+  <java-symbol type="drawable" name="ic_expand_bundle" />
+  <java-symbol type="drawable" name="ic_collapse_bundle" />
   <java-symbol type="dimen" name="notification_header_height" />
   <java-symbol type="dimen" name="notification_big_picture_content_min_height_with_picture" />
   <java-symbol type="dimen" name="notification_header_shrink_min_width" />
diff --git a/core/tests/benchmarks/Android.mk b/core/tests/benchmarks/Android.mk
new file mode 100644
index 0000000..25181b5
--- /dev/null
+++ b/core/tests/benchmarks/Android.mk
@@ -0,0 +1,30 @@
+# -*- mode: makefile -*-
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+# build framework base core benchmarks
+# ============================================================
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := frameworks-base-core-benchmarks
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_SRC_FILES := $(call all-java-files-under, src/)
+
+LOCAL_JAVA_LIBRARIES := \
+  caliper-api-target
+
+include $(BUILD_JAVA_LIBRARY)
diff --git a/core/tests/benchmarks/src/android/content/res/ResourcesBenchmark.java b/core/tests/benchmarks/src/android/content/res/ResourcesBenchmark.java
index 3638473..426b0dc 100644
--- a/core/tests/benchmarks/src/android/content/res/ResourcesBenchmark.java
+++ b/core/tests/benchmarks/src/android/content/res/ResourcesBenchmark.java
@@ -20,11 +20,13 @@
 import android.util.Xml;
 
 import com.android.internal.R;
-import com.google.caliper.SimpleBenchmark;
 
 import org.xmlpull.v1.XmlPullParser;
 
-public class ResourcesBenchmark extends SimpleBenchmark {
+import com.google.caliper.AfterExperiment;
+import com.google.caliper.BeforeExperiment;
+
+public class ResourcesBenchmark {
 
     private AssetManager mAsset;
     private Resources mRes;
@@ -34,7 +36,7 @@
     private int mIntegerId;
     private int mLayoutId;
 
-    @Override
+    @BeforeExperiment
     protected void setUp() {
         mAsset = new AssetManager();
         mAsset.addAssetPath("/system/framework/framework-res.apk");
@@ -46,7 +48,7 @@
         mLayoutId = mRes.getIdentifier("two_line_list_item", "layout", "android");
     }
 
-    @Override
+    @AfterExperiment
     protected void tearDown() {
         mAsset.close();
     }
diff --git a/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
index 1a50432..1b65603 100644
--- a/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
+++ b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
@@ -16,10 +16,10 @@
 
 package android.net;
 
+import com.google.caliper.BeforeExperiment;
 import com.google.caliper.Param;
-import com.google.caliper.SimpleBenchmark;
 
-public class NetworkStatsBenchmark extends SimpleBenchmark {
+public class NetworkStatsBenchmark {
     private static final String UNDERLYING_IFACE = "wlan0";
     private static final String TUN_IFACE = "tun0";
     private static final int TUN_UID = 999999999;
@@ -28,10 +28,8 @@
     private int mSize;
     private NetworkStats mNetworkStats;
 
-    @Override
+    @BeforeExperiment
     protected void setUp() throws Exception {
-        super.setUp();
-
         mNetworkStats = new NetworkStats(0, mSize + 2);
         int uid = 0;
         NetworkStats.Entry recycle = new NetworkStats.Entry();
diff --git a/core/tests/benchmarks/src/android/net/TrafficStatsBenchmark.java b/core/tests/benchmarks/src/android/net/TrafficStatsBenchmark.java
index 5a29adc..09de412 100644
--- a/core/tests/benchmarks/src/android/net/TrafficStatsBenchmark.java
+++ b/core/tests/benchmarks/src/android/net/TrafficStatsBenchmark.java
@@ -16,9 +16,7 @@
 
 package android.net;
 
-import com.google.caliper.SimpleBenchmark;
-
-public class TrafficStatsBenchmark extends SimpleBenchmark {
+public class TrafficStatsBenchmark {
     public void timeGetUidRxBytes(int reps) {
         for (int i = 0; i < reps; i++) {
             TrafficStats.getUidRxBytes(android.os.Process.myUid());
diff --git a/core/tests/benchmarks/src/android/os/ParcelArrayBenchmark.java b/core/tests/benchmarks/src/android/os/ParcelArrayBenchmark.java
index 21cfb09..eff8c8e 100644
--- a/core/tests/benchmarks/src/android/os/ParcelArrayBenchmark.java
+++ b/core/tests/benchmarks/src/android/os/ParcelArrayBenchmark.java
@@ -16,10 +16,11 @@
 
 package android.os;
 
+import com.google.caliper.AfterExperiment;
+import com.google.caliper.BeforeExperiment;
 import com.google.caliper.Param;
-import com.google.caliper.SimpleBenchmark;
 
-public class ParcelArrayBenchmark extends SimpleBenchmark {
+public class ParcelArrayBenchmark {
 
     @Param({ "1", "10", "100", "1000" })
     private int mSize;
@@ -34,7 +35,7 @@
     private Parcel mIntParcel;
     private Parcel mLongParcel;
 
-    @Override
+    @BeforeExperiment
     protected void setUp() {
         mWriteParcel = Parcel.obtain();
 
@@ -50,7 +51,7 @@
         mLongParcel.writeLongArray(mLongArray);
     }
 
-    @Override
+    @AfterExperiment
     protected void tearDown() {
         mWriteParcel.recycle();
         mWriteParcel = null;
@@ -118,5 +119,4 @@
             mLongParcel.readLongArray(mLongArray);
         }
     }
-
 }
diff --git a/core/tests/benchmarks/src/android/os/ParcelBenchmark.java b/core/tests/benchmarks/src/android/os/ParcelBenchmark.java
index 6a7b7c8..4bd2d00 100644
--- a/core/tests/benchmarks/src/android/os/ParcelBenchmark.java
+++ b/core/tests/benchmarks/src/android/os/ParcelBenchmark.java
@@ -16,18 +16,19 @@
 
 package android.os;
 
-import com.google.caliper.SimpleBenchmark;
+import com.google.caliper.AfterExperiment;
+import com.google.caliper.BeforeExperiment;
 
-public class ParcelBenchmark extends SimpleBenchmark {
+public class ParcelBenchmark {
 
     private Parcel mParcel;
 
-    @Override
+    @BeforeExperiment
     protected void setUp() {
         mParcel = Parcel.obtain();
     }
 
-    @Override
+    @AfterExperiment
     protected void tearDown() {
         mParcel.recycle();
         mParcel = null;
diff --git a/core/tests/benchmarks/src/android/os/StrictModeBenchmark.java b/core/tests/benchmarks/src/android/os/StrictModeBenchmark.java
index 41af3820..a110906 100644
--- a/core/tests/benchmarks/src/android/os/StrictModeBenchmark.java
+++ b/core/tests/benchmarks/src/android/os/StrictModeBenchmark.java
@@ -18,9 +18,7 @@
 
 import android.os.StrictMode.ThreadPolicy;
 
-import com.google.caliper.SimpleBenchmark;
-
-public class StrictModeBenchmark extends SimpleBenchmark {
+public class StrictModeBenchmark {
 
     private ThreadPolicy mOff = new ThreadPolicy.Builder().build();
     private ThreadPolicy mOn = new ThreadPolicy.Builder().detectAll().build();
diff --git a/core/tests/benchmarks/src/android/util/FloatMathBenchmark.java b/core/tests/benchmarks/src/android/util/FloatMathBenchmark.java
index 2858128..028dd1d 100644
--- a/core/tests/benchmarks/src/android/util/FloatMathBenchmark.java
+++ b/core/tests/benchmarks/src/android/util/FloatMathBenchmark.java
@@ -15,13 +15,9 @@
  */
 package android.util;
 
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-
 import android.util.FloatMath;
 
-public class FloatMathBenchmark extends SimpleBenchmark {
+public class FloatMathBenchmark {
 
     public float timeFloatMathCeil(int reps) {
         // Keep an answer so we don't optimize the method call away.
@@ -112,5 +108,4 @@
         }
         return f;
     }
-
 }
diff --git a/core/tests/benchmarks/src/com/android/internal/net/NetworkStatsFactoryBenchmark.java b/core/tests/benchmarks/src/com/android/internal/net/NetworkStatsFactoryBenchmark.java
index 2174be5..e62fbd6 100644
--- a/core/tests/benchmarks/src/com/android/internal/net/NetworkStatsFactoryBenchmark.java
+++ b/core/tests/benchmarks/src/com/android/internal/net/NetworkStatsFactoryBenchmark.java
@@ -18,29 +18,31 @@
 
 import android.net.NetworkStats;
 import android.os.SystemClock;
-
-import com.google.caliper.SimpleBenchmark;
-
+import com.google.caliper.AfterExperiment;
+import com.google.caliper.BeforeExperiment;
 import java.io.File;
 
-public class NetworkStatsFactoryBenchmark extends SimpleBenchmark {
+public class NetworkStatsFactoryBenchmark {
     private File mStats;
 
     // TODO: consider staging stats file with different number of rows
 
-    @Override
+    @BeforeExperiment
     protected void setUp() {
         mStats = new File("/proc/net/xt_qtaguid/stats");
     }
 
-    @Override
+    @AfterExperiment
     protected void tearDown() {
         mStats = null;
     }
 
     public void timeReadNetworkStatsDetailJava(int reps) throws Exception {
         for (int i = 0; i < reps; i++) {
-            NetworkStatsFactory.javaReadNetworkStatsDetail(mStats, NetworkStats.UID_ALL);
+            NetworkStatsFactory.javaReadNetworkStatsDetail(mStats, NetworkStats.UID_ALL,
+                    // Looks like this was broken by change d0c5b9abed60b7bc056d026bf0f2b2235410fb70
+                    // Fixed compilation problem but needs addressing properly.
+                    new String[0], 999);
         }
     }
 
@@ -48,7 +50,10 @@
         for (int i = 0; i < reps; i++) {
             final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
             NetworkStatsFactory.nativeReadNetworkStatsDetail(
-                    stats, mStats.getAbsolutePath(), NetworkStats.UID_ALL);
+                    stats, mStats.getAbsolutePath(), NetworkStats.UID_ALL,
+                    // Looks like this was broken by change d0c5b9abed60b7bc056d026bf0f2b2235410fb70
+                    // Fixed compilation problem but needs addressing properly.
+                    new String[0], 999);
         }
     }
 }
diff --git a/core/tests/benchmarks/src/com/android/internal/util/IndentingPrintWriterBenchmark.java b/core/tests/benchmarks/src/com/android/internal/util/IndentingPrintWriterBenchmark.java
index 34c73e8..1112d5c 100644
--- a/core/tests/benchmarks/src/com/android/internal/util/IndentingPrintWriterBenchmark.java
+++ b/core/tests/benchmarks/src/com/android/internal/util/IndentingPrintWriterBenchmark.java
@@ -17,15 +17,15 @@
 package com.android.internal.util;
 
 import com.google.android.collect.Lists;
-import com.google.caliper.SimpleBenchmark;
-
+import com.google.caliper.AfterExperiment;
+import com.google.caliper.BeforeExperiment;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 
-public class IndentingPrintWriterBenchmark extends SimpleBenchmark {
+public class IndentingPrintWriterBenchmark {
 
     private PrintWriter mDirect;
     private IndentingPrintWriter mIndenting;
@@ -33,7 +33,7 @@
     private Node mSimple;
     private Node mComplex;
 
-    @Override
+    @BeforeExperiment
     protected void setUp() throws IOException {
         final FileOutputStream os = new FileOutputStream(new File("/dev/null"));
         mDirect = new PrintWriter(os);
@@ -49,7 +49,7 @@
                 manyChildren);
     }
 
-    @Override
+    @AfterExperiment
     protected void tearDown() {
         mIndenting.close();
         mIndenting = null;
diff --git a/core/tests/coretests/res/layout/activity_text_view.xml b/core/tests/coretests/res/layout/activity_text_view.xml
index 7ab0b13..e795c10 100644
--- a/core/tests/coretests/res/layout/activity_text_view.xml
+++ b/core/tests/coretests/res/layout/activity_text_view.xml
@@ -23,6 +23,6 @@
     <EditText
             android:id="@+id/textview"
             android:layout_width="match_parent"
-            android:layout_height="match_parent" />
+            android:layout_height="wrap_content" />
 
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/core/tests/coretests/src/android/view/textservice/SpellCheckerSubtypeTest.java b/core/tests/coretests/src/android/view/textservice/SpellCheckerSubtypeTest.java
index 157c815..4a1c414 100644
--- a/core/tests/coretests/src/android/view/textservice/SpellCheckerSubtypeTest.java
+++ b/core/tests/coretests/src/android/view/textservice/SpellCheckerSubtypeTest.java
@@ -29,12 +29,20 @@
  * TODO: Most of part can be, and probably should be, moved to CTS.
  */
 public class SpellCheckerSubtypeTest extends InstrumentationTestCase {
+    private static final int SUBTYPE_SUBTYPE_ID_NONE = 0;
+    private static final String SUBTYPE_SUBTYPE_LOCALE_STRING_NONE = "";
+    private static final String SUBTYPE_SUBTYPE_LANGUAGE_TAG_NONE = "";
+
     private static final String SUBTYPE_SUBTYPE_LOCALE_STRING_A = "en_GB";
+    private static final String SUBTYPE_SUBTYPE_LANGUAGE_TAG_A = "en-GB";
     private static final int SUBTYPE_NAME_RES_ID_A = 0x12345;
     private static final String SUBTYPE_EXTRA_VALUE_A = "Key1=Value1,Key2=Value2";
+    private static final int SUBTYPE_SUBTYPE_ID_A = 42;
     private static final String SUBTYPE_SUBTYPE_LOCALE_STRING_B = "en_IN";
+    private static final String SUBTYPE_SUBTYPE_LANGUAGE_TAG_B = "en-IN";
     private static final int SUBTYPE_NAME_RES_ID_B = 0x54321;
     private static final String SUBTYPE_EXTRA_VALUE_B = "Key3=Value3,Key4=Value4";
+    private static final int SUBTYPE_SUBTYPE_ID_B = -42;
 
     private static int defaultHashCodeAlgorithm(String locale, String extraValue) {
         return Arrays.hashCode(new Object[] {locale, extraValue});
@@ -55,12 +63,13 @@
     }
 
     @SmallTest
-    public void testSubtype() throws Exception {
+    public void testSubtypeWithNoSubtypeId() throws Exception {
         final SpellCheckerSubtype subtype = new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A,
-                SUBTYPE_SUBTYPE_LOCALE_STRING_A, SUBTYPE_EXTRA_VALUE_A);
-
+                SUBTYPE_SUBTYPE_LOCALE_STRING_A, SUBTYPE_SUBTYPE_LANGUAGE_TAG_A,
+                SUBTYPE_EXTRA_VALUE_A, SUBTYPE_SUBTYPE_ID_NONE);
         assertEquals(SUBTYPE_NAME_RES_ID_A, subtype.getNameResId());
         assertEquals(SUBTYPE_SUBTYPE_LOCALE_STRING_A, subtype.getLocale());
+        assertEquals(SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, subtype.getLanguageTag());
         assertEquals("Value1", subtype.getExtraValueOf("Key1"));
         assertEquals("Value2", subtype.getExtraValueOf("Key2"));
         // Historically we have used SpellCheckerSubtype#hashCode() to track which subtype is
@@ -73,6 +82,7 @@
         final SpellCheckerSubtype clonedSubtype = cloneViaParcel(subtype);
         assertEquals(SUBTYPE_NAME_RES_ID_A, clonedSubtype.getNameResId());
         assertEquals(SUBTYPE_SUBTYPE_LOCALE_STRING_A, clonedSubtype.getLocale());
+        assertEquals(SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, clonedSubtype.getLanguageTag());
         assertEquals("Value1", clonedSubtype.getExtraValueOf("Key1"));
         assertEquals("Value2", clonedSubtype.getExtraValueOf("Key2"));
         assertEquals(
@@ -80,32 +90,67 @@
                 clonedSubtype.hashCode());
     }
 
+    public void testSubtypeWithSubtypeId() throws Exception {
+        final SpellCheckerSubtype subtype = new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A,
+                SUBTYPE_SUBTYPE_LOCALE_STRING_A, SUBTYPE_SUBTYPE_LANGUAGE_TAG_A,
+                SUBTYPE_EXTRA_VALUE_A, SUBTYPE_SUBTYPE_ID_A);
+
+        assertEquals(SUBTYPE_NAME_RES_ID_A, subtype.getNameResId());
+        assertEquals(SUBTYPE_SUBTYPE_LOCALE_STRING_A, subtype.getLocale());
+        assertEquals(SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, subtype.getLanguageTag());
+        assertEquals("Value1", subtype.getExtraValueOf("Key1"));
+        assertEquals("Value2", subtype.getExtraValueOf("Key2"));
+        // Similar to "SubtypeId" in InputMethodSubtype, "SubtypeId" in SpellCheckerSubtype enables
+        // developers to specify a stable and consistent ID for each subtype.
+        assertEquals(SUBTYPE_SUBTYPE_ID_A, subtype.hashCode());
+
+        final SpellCheckerSubtype clonedSubtype = cloneViaParcel(subtype);
+        assertEquals(SUBTYPE_NAME_RES_ID_A, clonedSubtype.getNameResId());
+        assertEquals(SUBTYPE_SUBTYPE_LOCALE_STRING_A, clonedSubtype.getLocale());
+        assertEquals(SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, clonedSubtype.getLanguageTag());
+        assertEquals("Value1", clonedSubtype.getExtraValueOf("Key1"));
+        assertEquals("Value2", clonedSubtype.getExtraValueOf("Key2"));
+        assertEquals(SUBTYPE_SUBTYPE_ID_A, clonedSubtype.hashCode());
+    }
+
     @SmallTest
     public void testGetLocaleObject() throws Exception {
-        assertEquals(new Locale("en"), new SpellCheckerSubtype(
-                SUBTYPE_NAME_RES_ID_A, "en", SUBTYPE_EXTRA_VALUE_A).getLocaleObject());
-        assertEquals(new Locale("en", "US"), new SpellCheckerSubtype(
-                SUBTYPE_NAME_RES_ID_A, "en_US", SUBTYPE_EXTRA_VALUE_A).getLocaleObject());
-        assertEquals(new Locale("en", "US", "POSIX"), new SpellCheckerSubtype(
-                SUBTYPE_NAME_RES_ID_A, "en_US_POSIX", SUBTYPE_EXTRA_VALUE_A).getLocaleObject());
+        assertEquals(new Locale("en", "GB"),
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, "en_GB",
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_NONE, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_NONE).getLocaleObject());
+        assertEquals(new Locale("en", "GB"),
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_NONE,
+                        "en-GB", SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_NONE).getLocaleObject());
 
-        // Special rewrite rule for "tl" for versions of Android earlier than Lollipop that did not
-        // support three letter language codes, and used "tl" (Tagalog) as the language string for
-        // "fil" (Filipino).
-        assertEquals(new Locale("fil"), new SpellCheckerSubtype(
-                SUBTYPE_NAME_RES_ID_A, "tl", SUBTYPE_EXTRA_VALUE_A).getLocaleObject());
-        assertEquals(new Locale("fil", "PH"), new SpellCheckerSubtype(
-                SUBTYPE_NAME_RES_ID_A, "tl_PH", SUBTYPE_EXTRA_VALUE_A).getLocaleObject());
-        assertEquals(new Locale("fil", "PH", "POSIX"), new SpellCheckerSubtype(
-                SUBTYPE_NAME_RES_ID_A, "tl_PH_POSIX", SUBTYPE_EXTRA_VALUE_A).getLocaleObject());
+        // If neither locale string nor language tag is specified,
+        // {@link SpellCheckerSubtype#getLocaleObject} returns null.
+        assertNull(
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_NONE,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_NONE, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_NONE).getLocaleObject());
 
-        // So far rejecting invalid/unexpected locale strings is out of the scope.
-        assertEquals(new Locale("a"), new SpellCheckerSubtype(
-                SUBTYPE_NAME_RES_ID_A, "a", SUBTYPE_EXTRA_VALUE_A).getLocaleObject());
-        assertEquals(new Locale("a b c"), new SpellCheckerSubtype(
-                SUBTYPE_NAME_RES_ID_A, "a b c", SUBTYPE_EXTRA_VALUE_A).getLocaleObject());
-        assertEquals(new Locale("en-US"), new SpellCheckerSubtype(
-                SUBTYPE_NAME_RES_ID_A, "en-US", SUBTYPE_EXTRA_VALUE_A).getLocaleObject());
+        // If both locale string and language tag are specified,
+        // {@link SpellCheckerSubtype#getLocaleObject} uses language tag.
+        assertEquals(new Locale("en", "GB"),
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, "en_US", "en-GB",
+                        SUBTYPE_EXTRA_VALUE_A, SUBTYPE_SUBTYPE_ID_NONE).getLocaleObject());
+
+        // Make sure that "tl_PH" is rewritten to "fil_PH" for spell checkers that need to support
+        // Android KitKat and prior, which do not support 3-letter language codes.
+        assertEquals(new Locale("fil", "PH"),
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, "tl_PH",
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_NONE, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_NONE).getLocaleObject());
+
+        // "languageTag" attribute is available in Android N and later, where 3-letter country codes
+        // are guaranteed to be available.  It's developers' responsibility for specifying a valid
+        // country subtags here and we do not rewrite "tl" to "fil" for simplicity.
+        assertEquals("tl",
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_NONE,
+                        "tl-PH", SUBTYPE_EXTRA_VALUE_A, SUBTYPE_SUBTYPE_ID_NONE)
+                        .getLocaleObject().getLanguage());
     }
 
     @SmallTest
@@ -130,5 +175,87 @@
                         SUBTYPE_EXTRA_VALUE_A),
                 new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_A,
                         SUBTYPE_EXTRA_VALUE_B));
+
+        // If subtype ID is 0 (== SUBTYPE_SUBTYPE_ID_NONE), we keep the same behavior.
+        assertEquals(
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_A,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_NONE),
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_A,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_NONE));
+        assertNotEqual(
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_A,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_NONE),
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_B, SUBTYPE_SUBTYPE_LOCALE_STRING_B,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_NONE));
+        assertNotEqual(
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_A,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_NONE),
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_B,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_NONE));
+        assertNotEqual(
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_A,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_NONE),
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_A,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_B, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_NONE));
+        assertNotEqual(
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_A,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_NONE),
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_A,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, SUBTYPE_EXTRA_VALUE_B,
+                        SUBTYPE_SUBTYPE_ID_NONE));
+
+        // If subtype ID is not 0, we test the equality based only on the subtype ID.
+        assertEquals(
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_A,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_A),
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_A,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_A));
+        assertEquals(
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_A,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_A),
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_B, SUBTYPE_SUBTYPE_LOCALE_STRING_B,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_A));
+        assertEquals(
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_A,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_A),
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_B,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_A));
+        assertEquals(
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_A,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_A),
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_A,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_B, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_A));
+        assertEquals(
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_A,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_A),
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_A,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, SUBTYPE_EXTRA_VALUE_B,
+                        SUBTYPE_SUBTYPE_ID_A));
+        assertNotEqual(
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_A,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_A),
+                new SpellCheckerSubtype(SUBTYPE_NAME_RES_ID_A, SUBTYPE_SUBTYPE_LOCALE_STRING_A,
+                        SUBTYPE_SUBTYPE_LANGUAGE_TAG_A, SUBTYPE_EXTRA_VALUE_A,
+                        SUBTYPE_SUBTYPE_ID_B));
     }
+
 }
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java b/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java
index ddbdc87..83a9e01 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java
@@ -16,15 +16,23 @@
 
 package android.widget;
 
+import static android.widget.espresso.DragHandleUtils.assertNoSelectionHandles;
+import static android.widget.espresso.DragHandleUtils.onHandleView;
+import static android.widget.espresso.TextViewActions.mouseClickOnTextAtIndex;
 import static android.widget.espresso.TextViewActions.mouseDoubleClickOnTextAtIndex;
 import static android.widget.espresso.TextViewActions.mouseLongClickOnTextAtIndex;
 import static android.widget.espresso.TextViewActions.mouseDoubleClickAndDragOnText;
 import static android.widget.espresso.TextViewActions.mouseDragOnText;
 import static android.widget.espresso.TextViewActions.mouseLongClickAndDragOnText;
+import static android.widget.espresso.TextViewActions.mouseTripleClickAndDragOnText;
+import static android.widget.espresso.TextViewActions.mouseTripleClickOnTextAtIndex;
 import static android.widget.espresso.TextViewAssertions.hasSelection;
 import static android.support.test.espresso.Espresso.onView;
 import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.action.ViewActions.replaceText;
 import static android.support.test.espresso.action.ViewActions.typeTextIntoFocusedView;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
 import static android.support.test.espresso.matcher.ViewMatchers.withId;
 
 import com.android.frameworks.coretests.R;
@@ -48,10 +56,23 @@
         final String helloWorld = "Hello world!";
         onView(withId(R.id.textview)).perform(click());
         onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
+
+        assertNoSelectionHandles();
+
         onView(withId(R.id.textview)).perform(
                 mouseDragOnText(helloWorld.indexOf("llo"), helloWorld.indexOf("ld!")));
 
         onView(withId(R.id.textview)).check(hasSelection("llo wor"));
+
+        onHandleView(com.android.internal.R.id.selection_start_handle)
+                .check(matches(isDisplayed()));
+        onHandleView(com.android.internal.R.id.selection_end_handle)
+                .check(matches(isDisplayed()));
+
+        onView(withId(R.id.textview)).perform(mouseClickOnTextAtIndex(helloWorld.indexOf("w")));
+        onView(withId(R.id.textview)).check(hasSelection(""));
+
+        assertNoSelectionHandles();
     }
 
     @SmallTest
@@ -89,6 +110,9 @@
         onView(withId(R.id.textview)).perform(mouseLongClickOnTextAtIndex(
                 helloWorld.indexOf("rld")));
         onView(withId(R.id.textview)).check(hasSelection("world"));
+
+        onView(withId(R.id.textview)).perform(mouseLongClickOnTextAtIndex(helloWorld.length()));
+        onView(withId(R.id.textview)).check(hasSelection("!"));
     }
 
     @SmallTest
@@ -113,6 +137,9 @@
         onView(withId(R.id.textview)).perform(mouseDoubleClickOnTextAtIndex(
                 helloWorld.indexOf("rld")));
         onView(withId(R.id.textview)).check(hasSelection("world"));
+
+        onView(withId(R.id.textview)).perform(mouseDoubleClickOnTextAtIndex(helloWorld.length()));
+        onView(withId(R.id.textview)).check(hasSelection("!"));
     }
 
     @SmallTest
@@ -166,4 +193,102 @@
                 mouseLongClickAndDragOnText(text.indexOf("j"), text.indexOf("f")));
         onView(withId(R.id.textview)).check(hasSelection("efg hijk"));
     }
+
+    @SmallTest
+    public void testSelectTextByTripleClick() throws Exception {
+        getActivity();
+
+        final StringBuilder builder = new StringBuilder();
+        builder.append("First paragraph.\n");
+        builder.append("Second paragraph.");
+        for (int i = 0; i < 10; i++) {
+            builder.append(" This paragraph is very long.");
+        }
+        builder.append('\n');
+        builder.append("Third paragraph.");
+        final String text = builder.toString();
+
+        onView(withId(R.id.textview)).perform(click());
+        onView(withId(R.id.textview)).perform(replaceText(text));
+
+        onView(withId(R.id.textview)).perform(
+                mouseTripleClickOnTextAtIndex(text.indexOf("rst")));
+        onView(withId(R.id.textview)).check(hasSelection("First paragraph.\n"));
+
+        onView(withId(R.id.textview)).perform(
+                mouseTripleClickOnTextAtIndex(text.indexOf("cond")));
+        onView(withId(R.id.textview)).check(hasSelection(
+                text.substring(text.indexOf("Second"), text.indexOf("Third"))));
+
+        onView(withId(R.id.textview)).perform(
+                mouseTripleClickOnTextAtIndex(text.indexOf("ird")));
+        onView(withId(R.id.textview)).check(hasSelection("Third paragraph."));
+
+        onView(withId(R.id.textview)).perform(
+                mouseTripleClickOnTextAtIndex(text.indexOf("very long")));
+        onView(withId(R.id.textview)).check(hasSelection(
+                text.substring(text.indexOf("Second"), text.indexOf("Third"))));
+    }
+
+    @SmallTest
+    public void testSelectTextByTripleClickAndDrag() throws Exception {
+        getActivity();
+
+        final StringBuilder builder = new StringBuilder();
+        builder.append("First paragraph.\n");
+        builder.append("Second paragraph.");
+        for (int i = 0; i < 10; i++) {
+            builder.append(" This paragraph is very long.");
+        }
+        builder.append('\n');
+        builder.append("Third paragraph.");
+        final String text = builder.toString();
+
+        onView(withId(R.id.textview)).perform(click());
+        onView(withId(R.id.textview)).perform(replaceText(text));
+
+        onView(withId(R.id.textview)).perform(
+                mouseTripleClickAndDragOnText(text.indexOf("irst"), text.indexOf("st")));
+        onView(withId(R.id.textview)).check(hasSelection("First paragraph.\n"));
+
+        onView(withId(R.id.textview)).perform(
+                mouseTripleClickAndDragOnText(text.indexOf("cond"), text.indexOf("Third") - 2));
+        onView(withId(R.id.textview)).check(hasSelection(
+                text.substring(text.indexOf("Second"), text.indexOf("Third"))));
+
+        onView(withId(R.id.textview)).perform(
+                mouseTripleClickAndDragOnText(text.indexOf("First"), text.indexOf("ird")));
+        onView(withId(R.id.textview)).check(hasSelection(text));
+    }
+
+    @SmallTest
+    public void testSelectTextByTripleClickAndDrag_reverse() throws Exception {
+        getActivity();
+
+        final StringBuilder builder = new StringBuilder();
+        builder.append("First paragraph.\n");
+        builder.append("Second paragraph.");
+        for (int i = 0; i < 10; i++) {
+            builder.append(" This paragraph is very long.");
+        }
+        builder.append('\n');
+        builder.append("Third paragraph.");
+        final String text = builder.toString();
+
+        onView(withId(R.id.textview)).perform(click());
+        onView(withId(R.id.textview)).perform(replaceText(text));
+
+        onView(withId(R.id.textview)).perform(
+                mouseTripleClickAndDragOnText(text.indexOf("st"), text.indexOf("irst")));
+        onView(withId(R.id.textview)).check(hasSelection("First paragraph.\n"));
+
+        onView(withId(R.id.textview)).perform(
+                mouseTripleClickAndDragOnText(text.indexOf("Third") - 2, text.indexOf("cond")));
+        onView(withId(R.id.textview)).check(hasSelection(
+                text.substring(text.indexOf("Second"), text.indexOf("Third"))));
+
+        onView(withId(R.id.textview)).perform(
+                mouseTripleClickAndDragOnText(text.indexOf("ird"), text.indexOf("First")));
+        onView(withId(R.id.textview)).check(hasSelection(text));
+    }
 }
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
index 4614505..e54723e 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
@@ -16,6 +16,8 @@
 
 package android.widget;
 
+import static android.widget.espresso.DragHandleUtils.assertNoSelectionHandles;
+import static android.widget.espresso.DragHandleUtils.onHandleView;
 import static android.widget.espresso.TextViewActions.clickOnTextAtIndex;
 import static android.widget.espresso.TextViewActions.doubleTapAndDragOnText;
 import static android.widget.espresso.TextViewActions.doubleClickOnTextAtIndex;
@@ -26,24 +28,22 @@
 import static android.widget.espresso.TextViewAssertions.hasInsertionPointerAtIndex;
 import static android.widget.espresso.TextViewAssertions.hasSelection;
 import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarIsDisplayed;
+import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarIsNotDisplayed;
+import static android.widget.espresso.FloatingToolbarEspressoUtils.sleepForFloatingToolbarPopup;
+import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarContainsItem;
+import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarDoesNotContainItem;
 import static android.support.test.espresso.Espresso.onView;
 import static android.support.test.espresso.action.ViewActions.click;
 import static android.support.test.espresso.action.ViewActions.pressKey;
+import static android.support.test.espresso.action.ViewActions.replaceText;
 import static android.support.test.espresso.action.ViewActions.typeTextIntoFocusedView;
 import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
-import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant;
-import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
 import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
 import static android.support.test.espresso.matcher.ViewMatchers.withId;
 import static android.support.test.espresso.matcher.ViewMatchers.withText;
-import static org.hamcrest.Matchers.allOf;
 
 import com.android.frameworks.coretests.R;
 
-import android.support.test.espresso.NoMatchingRootException;
-import android.support.test.espresso.NoMatchingViewException;
-import android.support.test.espresso.ViewInteraction;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.view.KeyEvent;
@@ -153,19 +153,115 @@
 
     @SmallTest
     public void testToolbarAppearsAfterSelection() throws Exception {
-        // It'll be nice to check that the toolbar is not visible (or does not exist) here
-        // I can't currently find a way to do this. I'll get to it later.
-
         final String text = "Toolbar appears after selection.";
         onView(withId(R.id.textview)).perform(click());
+        assertFloatingToolbarIsNotDisplayed();
         onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
         onView(withId(R.id.textview)).perform(
                 longPressOnTextAtIndex(text.indexOf("appears")));
 
-        // It takes the toolbar less than 100ms to start to animate into screen.
-        // Ideally, we'll wait using the UiController, but I guess this works for now.
-        Thread.sleep(100);
-        assertFloatingToolbarIsDisplayed(getActivity());
+        sleepForFloatingToolbarPopup();
+        assertFloatingToolbarIsDisplayed();
+
+        final String text2 = "Toolbar disappears after typing text.";
+        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text2));
+        assertFloatingToolbarIsNotDisplayed();
+    }
+
+    @SmallTest
+    public void testToolbarAndInsertionHandle() throws Exception {
+        final String text = "text";
+        onView(withId(R.id.textview)).perform(click());
+        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
+        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
+        assertFloatingToolbarIsNotDisplayed();
+
+        onHandleView(com.android.internal.R.id.insertion_handle).perform(click());
+        sleepForFloatingToolbarPopup();
+        assertFloatingToolbarIsDisplayed();
+
+        assertFloatingToolbarContainsItem(
+                getActivity().getString(com.android.internal.R.string.selectAll));
+        assertFloatingToolbarDoesNotContainItem(
+                getActivity().getString(com.android.internal.R.string.copy));
+        assertFloatingToolbarDoesNotContainItem(
+                getActivity().getString(com.android.internal.R.string.cut));
+    }
+
+    @SmallTest
+    public void testToolbarAndSelectionHandle() throws Exception {
+        final String text = "abcd efg hijk";
+        onView(withId(R.id.textview)).perform(click());
+        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
+
+        onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf("f")));
+        sleepForFloatingToolbarPopup();
+        assertFloatingToolbarIsDisplayed();
+
+        assertFloatingToolbarContainsItem(
+                getActivity().getString(com.android.internal.R.string.selectAll));
+        assertFloatingToolbarContainsItem(
+                getActivity().getString(com.android.internal.R.string.copy));
+        assertFloatingToolbarContainsItem(
+                getActivity().getString(com.android.internal.R.string.cut));
+
+        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+        onHandleView(com.android.internal.R.id.selection_start_handle)
+                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a')));
+        sleepForFloatingToolbarPopup();
+        assertFloatingToolbarIsDisplayed();
+
+        onHandleView(com.android.internal.R.id.selection_end_handle)
+                .perform(dragHandle(textView, Handle.SELECTION_END, text.length()));
+        sleepForFloatingToolbarPopup();
+        assertFloatingToolbarIsDisplayed();
+
+        assertFloatingToolbarDoesNotContainItem(
+                getActivity().getString(com.android.internal.R.string.selectAll));
+        assertFloatingToolbarContainsItem(
+                getActivity().getString(com.android.internal.R.string.copy));
+        assertFloatingToolbarContainsItem(
+                getActivity().getString(com.android.internal.R.string.cut));
+    }
+
+    @SmallTest
+    public void testInsertionHandle() throws Exception {
+        final String text = "abcd efg hijk ";
+        onView(withId(R.id.textview)).perform(click());
+        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
+
+        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
+        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.length()));
+
+        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+
+        onHandleView(com.android.internal.R.id.insertion_handle)
+                .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('a')));
+        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("a")));
+
+        onHandleView(com.android.internal.R.id.insertion_handle)
+                .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('f')));
+        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("f")));
+    }
+
+    @SmallTest
+    public void testInsertionHandle_multiLine() throws Exception {
+        final String text = "abcd\n" + "efg\n" + "hijk\n";
+        onView(withId(R.id.textview)).perform(click());
+        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
+
+        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
+        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.length()));
+
+        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
+
+        onHandleView(com.android.internal.R.id.insertion_handle)
+                .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('a')));
+        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("a")));
+
+        onHandleView(com.android.internal.R.id.insertion_handle)
+                .perform(dragHandle(textView, Handle.INSERTION, text.indexOf('f')));
+        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("f")));
     }
 
     @SmallTest
@@ -183,7 +279,7 @@
         onHandleView(com.android.internal.R.id.selection_end_handle)
                 .check(matches(isDisplayed()));
 
-        final TextView textView = (TextView)getActivity().findViewById(R.id.textview);
+        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
         onHandleView(com.android.internal.R.id.selection_start_handle)
                 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('a')));
         onView(withId(R.id.textview)).check(hasSelection("abcd efg"));
@@ -200,7 +296,7 @@
         onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
         onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('i')));
 
-        final TextView textView = (TextView)getActivity().findViewById(R.id.textview);
+        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
         onHandleView(com.android.internal.R.id.selection_start_handle)
                 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('e')));
         onView(withId(R.id.textview)).check(hasSelection("efg\nhijk"));
@@ -219,13 +315,46 @@
     }
 
     @SmallTest
+    public void testSelectionHandles_multiLine_rtl() throws Exception {
+        // Arabic text.
+        final String text = "\u062A\u062B\u062C\n" + "\u062D\u062E\u062F\n"
+                + "\u0630\u0631\u0632\n" + "\u0633\u0634\u0635\n" + "\u0636\u0637\u0638\n"
+                + "\u0639\u063A\u063B";
+        onView(withId(R.id.textview)).perform(click());
+        onView(withId(R.id.textview)).perform(replaceText(text));
+        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.length()));
+        onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('\u0634')));
+
+        final TextView textView = (TextView)getActivity().findViewById(R.id.textview);
+        onHandleView(com.android.internal.R.id.selection_start_handle)
+                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('\u062E')));
+        onView(withId(R.id.textview)).check(hasSelection(
+                text.substring(text.indexOf('\u062D'), text.indexOf('\u0635') + 1)));
+
+        onHandleView(com.android.internal.R.id.selection_start_handle)
+                .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('\u062A')));
+        onView(withId(R.id.textview)).check(hasSelection(
+                text.substring(text.indexOf('\u062A'), text.indexOf('\u0635') + 1)));
+
+        onHandleView(com.android.internal.R.id.selection_end_handle)
+                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('\u0638')));
+        onView(withId(R.id.textview)).check(hasSelection(
+                text.substring(text.indexOf('\u062A'), text.indexOf('\u0638') + 1)));
+
+        onHandleView(com.android.internal.R.id.selection_end_handle)
+                .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('\u063B')));
+        onView(withId(R.id.textview)).check(hasSelection(text));
+    }
+
+
+    @SmallTest
     public void testSelectionHandles_doesNotPassAnotherHandle() throws Exception {
         final String text = "abcd efg hijk lmn";
         onView(withId(R.id.textview)).perform(click());
         onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
         onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('f')));
 
-        final TextView textView = (TextView)getActivity().findViewById(R.id.textview);
+        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
         onHandleView(com.android.internal.R.id.selection_start_handle)
                 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('l')));
         onView(withId(R.id.textview)).check(hasSelection("g"));
@@ -243,7 +372,7 @@
         onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
         onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('i')));
 
-        final TextView textView = (TextView)getActivity().findViewById(R.id.textview);
+        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
         onHandleView(com.android.internal.R.id.selection_start_handle)
                 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('r') + 1));
         onView(withId(R.id.textview)).check(hasSelection("k"));
@@ -261,7 +390,7 @@
         onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
         onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('i')));
 
-        final TextView textView = (TextView)getActivity().findViewById(R.id.textview);
+        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
 
         onHandleView(com.android.internal.R.id.selection_start_handle)
                 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('f')));
@@ -314,7 +443,7 @@
         onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
         onView(withId(R.id.textview)).perform(doubleClickOnTextAtIndex(text.indexOf('m')));
 
-        final TextView textView = (TextView)getActivity().findViewById(R.id.textview);
+        final TextView textView = (TextView) getActivity().findViewById(R.id.textview);
 
         onHandleView(com.android.internal.R.id.selection_start_handle)
                 .perform(dragHandle(textView, Handle.SELECTION_START, text.indexOf('c')));
@@ -342,25 +471,4 @@
                 .perform(dragHandle(textView, Handle.SELECTION_END, text.indexOf('i')));
         onView(withId(R.id.textview)).check(hasSelection("hijk"));
     }
-
-    private static void assertNoSelectionHandles() {
-        try {
-            onHandleView(com.android.internal.R.id.selection_start_handle)
-                    .check(matches(isDisplayed()));
-        } catch (NoMatchingRootException | NoMatchingViewException | AssertionError e) {
-            try {
-                onHandleView(com.android.internal.R.id.selection_end_handle)
-                        .check(matches(isDisplayed()));
-            } catch (NoMatchingRootException | NoMatchingViewException | AssertionError e1) {
-                return;
-            }
-        }
-        throw new AssertionError("Selection handle found");
-    }
-
-    private static ViewInteraction onHandleView(int id)
-            throws NoMatchingRootException, NoMatchingViewException, AssertionError {
-        return onView(allOf(withId(id), isAssignableFrom(Editor.HandleView.class)))
-                .inRoot(withDecorView(hasDescendant(withId(id))));
-    }
 }
diff --git a/core/tests/coretests/src/android/widget/espresso/DragAction.java b/core/tests/coretests/src/android/widget/espresso/DragAction.java
index ce97568..b2c8e38 100644
--- a/core/tests/coretests/src/android/widget/espresso/DragAction.java
+++ b/core/tests/coretests/src/android/widget/espresso/DragAction.java
@@ -157,6 +157,59 @@
         },
 
         /**
+         * Starts a drag with a mouse triple click.
+         */
+        MOUSE_TRIPLE_CLICK {
+            private DownMotionPerformer downMotion = new DownMotionPerformer() {
+                @Override
+                @Nullable
+                public MotionEvent perform(
+                        UiController uiController, float[] coordinates, float[] precision) {
+                    MotionEvent downEvent = MotionEvents.sendDown(
+                            uiController, coordinates, precision)
+                            .down;
+                    for (int i = 0; i < 2; ++i) {
+                        try {
+                            if (!MotionEvents.sendUp(uiController, downEvent)) {
+                                String logMessage = "Injection of up event as part of the triple "
+                                        + "click failed. Sending cancel event.";
+                                Log.d(TAG, logMessage);
+                                MotionEvents.sendCancel(uiController, downEvent);
+                                return null;
+                            }
+
+                            long doubleTapMinimumTimeout = ViewConfiguration.getDoubleTapMinTime();
+                            uiController.loopMainThreadForAtLeast(doubleTapMinimumTimeout);
+                        } finally {
+                            downEvent.recycle();
+                        }
+                        downEvent = MotionEvents.sendDown(
+                                uiController, coordinates, precision).down;
+                    }
+                    return downEvent;
+                }
+            };
+
+            @Override
+            public Status sendSwipe(
+                    UiController uiController,
+                    float[] startCoordinates, float[] endCoordinates, float[] precision) {
+                return sendLinearDrag(
+                        uiController, downMotion, startCoordinates, endCoordinates, precision);
+            }
+
+            @Override
+            public String toString() {
+                return "mouse triple click and drag to select";
+            }
+
+            @Override
+            public UiController wrapUiController(UiController uiController) {
+                return new MouseUiController(uiController);
+            }
+        },
+
+        /**
          * Starts a drag with a tap.
          */
         TAP {
diff --git a/core/tests/coretests/src/android/widget/espresso/DragHandleUtils.java b/core/tests/coretests/src/android/widget/espresso/DragHandleUtils.java
new file mode 100644
index 0000000..f744cae
--- /dev/null
+++ b/core/tests/coretests/src/android/widget/espresso/DragHandleUtils.java
@@ -0,0 +1,58 @@
+/*
+ * 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.widget.espresso;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
+import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant;
+import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static org.hamcrest.Matchers.allOf;
+
+import android.support.test.espresso.NoMatchingRootException;
+import android.support.test.espresso.NoMatchingViewException;
+import android.support.test.espresso.ViewInteraction;
+import android.widget.Editor;
+
+public class DragHandleUtils {
+    private DragHandleUtils() {
+
+    }
+
+    public static void assertNoSelectionHandles() {
+        try {
+            onHandleView(com.android.internal.R.id.selection_start_handle)
+                    .check(matches(isDisplayed()));
+        } catch (NoMatchingRootException | NoMatchingViewException | AssertionError e) {
+            try {
+                onHandleView(com.android.internal.R.id.selection_end_handle)
+                        .check(matches(isDisplayed()));
+            } catch (NoMatchingRootException | NoMatchingViewException | AssertionError e1) {
+                return;
+            }
+        }
+        throw new AssertionError("Selection handle found");
+    }
+
+    public static ViewInteraction onHandleView(int id)
+            throws NoMatchingRootException, NoMatchingViewException, AssertionError {
+        return onView(allOf(withId(id), isAssignableFrom(Editor.HandleView.class)))
+                .inRoot(withDecorView(hasDescendant(withId(id))));
+    }
+}
diff --git a/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java b/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java
index fc01d84..f02fe00 100644
--- a/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java
+++ b/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java
@@ -19,31 +19,133 @@
 import static android.support.test.espresso.Espresso.onView;
 import static android.support.test.espresso.assertion.ViewAssertions.matches;
 import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
+import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant;
 import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.isRoot;
 import static android.support.test.espresso.matcher.ViewMatchers.withTagValue;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static org.hamcrest.Matchers.allOf;
 import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
 
-import android.app.Activity;
+import org.hamcrest.Matcher;
+
+import android.support.test.espresso.NoMatchingRootException;
+import android.support.test.espresso.NoMatchingViewException;
+import android.support.test.espresso.UiController;
+import android.support.test.espresso.ViewAction;
+import android.support.test.espresso.ViewInteraction;
+import android.support.test.espresso.action.ViewActions;
+import android.support.test.espresso.matcher.ViewMatchers;
+import android.view.View;
+
 import com.android.internal.widget.FloatingToolbar;
 
 /**
  * Espresso utility methods for the floating toolbar.
  */
 public class FloatingToolbarEspressoUtils {
-
+    private final static Object TAG = FloatingToolbar.FLOATING_TOOLBAR_TAG;
 
     private FloatingToolbarEspressoUtils() {}
 
+    private static ViewInteraction onFloatingToolBar() {
+        return onView(withTagValue(is(TAG)))
+                .inRoot(withDecorView(hasDescendant(withTagValue(is(TAG)))));
+    }
+
     /**
      * Asserts that the floating toolbar is displayed on screen.
      *
      * @throws AssertionError if the assertion fails
      */
-    public static void assertFloatingToolbarIsDisplayed(Activity activity) {
-        onView(withTagValue(is((Object) FloatingToolbar.FLOATING_TOOLBAR_TAG)))
-                .inRoot(withDecorView(not(is(activity.getWindow().getDecorView()))))
-                .check(matches(isDisplayed()));
+    public static void assertFloatingToolbarIsDisplayed() {
+        onFloatingToolBar().check(matches(isDisplayed()));
     }
 
+    /**
+     * Asserts that the floating toolbar is not displayed on screen.
+     *
+     * @throws AssertionError if the assertion fails
+     */
+    public static void assertFloatingToolbarIsNotDisplayed() {
+        try {
+            onFloatingToolBar().check(matches(isDisplayed()));
+        } catch (NoMatchingRootException | NoMatchingViewException | AssertionError e) {
+            return;
+        }
+        throw new AssertionError("Floating toolbar is displayed");
+    }
+
+    private static void toggleOverflow() {
+        final int id = com.android.internal.R.id.overflow;
+        onView(allOf(withId(id), isDisplayed()))
+                .inRoot(withDecorView(hasDescendant(withId(id))))
+                .perform(ViewActions.click());
+        onView(isRoot()).perform(SLEEP);
+    }
+
+    public static void sleepForFloatingToolbarPopup() {
+        onView(isRoot()).perform(SLEEP);
+    }
+
+    /**
+     * Asserts that the floating toolbar contains the specified item.
+     *
+     * @param itemLabel label of the item.
+     * @throws AssertionError if the assertion fails
+     */
+    public static void assertFloatingToolbarContainsItem(String itemLabel) {
+        try{
+            onFloatingToolBar().check(matches(hasDescendant(ViewMatchers.withText(itemLabel))));
+        } catch (AssertionError e) {
+            try{
+                toggleOverflow();
+            } catch (NoMatchingViewException | NoMatchingRootException e2) {
+                // No overflow items.
+                throw e;
+            }
+            try{
+                onFloatingToolBar().check(matches(hasDescendant(ViewMatchers.withText(itemLabel))));
+            } finally {
+                toggleOverflow();
+            }
+        }
+    }
+
+    /**
+     * Asserts that the floating toolbar doesn't contain the specified item.
+     *
+     * @param itemLabel label of the item.
+     * @throws AssertionError if the assertion fails
+     */
+    public static void assertFloatingToolbarDoesNotContainItem(String itemLabel) {
+        try{
+            assertFloatingToolbarContainsItem(itemLabel);
+        } catch (AssertionError e) {
+            return;
+        }
+        throw new AssertionError("Floating toolbar contains " + itemLabel);
+    }
+
+    /**
+     * ViewAction to sleep to wait floating toolbar's animation.
+     */
+    private static final ViewAction SLEEP = new ViewAction() {
+        private static final long SLEEP_DURATION = 400;
+
+        @Override
+        public Matcher<View> getConstraints() {
+            return isDisplayed();
+        }
+
+        @Override
+        public String getDescription() {
+            return "Sleep " + SLEEP_DURATION + " ms.";
+        }
+
+        @Override
+        public void perform(UiController uiController, View view) {
+            uiController.loopMainThreadForAtLeast(SLEEP_DURATION);
+        }
+    };
 }
diff --git a/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java b/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java
index de640ca..e51f2785 100644
--- a/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java
+++ b/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java
@@ -22,9 +22,13 @@
 import android.support.test.espresso.ViewAction;
 import android.support.test.espresso.action.CoordinatesProvider;
 import android.support.test.espresso.action.GeneralClickAction;
+import android.support.test.espresso.action.MotionEvents;
+import android.support.test.espresso.action.MotionEvents.DownResultHolder;
 import android.support.test.espresso.action.PrecisionDescriber;
+import android.support.test.espresso.action.Press;
 import android.support.test.espresso.action.Tapper;
 import android.view.View;
+import android.view.ViewConfiguration;
 
 /**
  * ViewAction for performing an click on View by a mouse.
@@ -32,10 +36,58 @@
 public final class MouseClickAction implements ViewAction {
     private final GeneralClickAction mGeneralClickAction;
 
-    public MouseClickAction(Tapper tapper, CoordinatesProvider coordinatesProvider,
-            PrecisionDescriber precisionDescriber) {
+    public enum CLICK implements Tapper {
+        TRIPLE {
+            @Override
+            public Tapper.Status sendTap(UiController uiController, float[] coordinates,
+                    float[] precision) {
+                Tapper.Status stat = sendSingleTap(uiController, coordinates, precision);
+                boolean warning = false;
+                if (stat == Tapper.Status.FAILURE) {
+                    return Tapper.Status.FAILURE;
+                } else if (stat == Tapper.Status.WARNING) {
+                    warning = true;
+                }
+
+                long doubleTapMinimumTimeout = ViewConfiguration.getDoubleTapMinTime();
+                for (int i = 0; i < 2; i++) {
+                    if (0 < doubleTapMinimumTimeout) {
+                        uiController.loopMainThreadForAtLeast(doubleTapMinimumTimeout);
+                    }
+                    stat = sendSingleTap(uiController, coordinates, precision);
+                    if (stat == Tapper.Status.FAILURE) {
+                        return Tapper.Status.FAILURE;
+                    } else if (stat == Tapper.Status.WARNING) {
+                        warning = true;
+                    }
+                }
+
+                if (warning) {
+                    return Tapper.Status.WARNING;
+                } else {
+                    return Tapper.Status.SUCCESS;
+                }
+            }
+        };
+
+        private static Tapper.Status sendSingleTap(UiController uiController,
+                float[] coordinates, float[] precision) {
+            DownResultHolder res = MotionEvents.sendDown(uiController, coordinates, precision);
+            try {
+                if (!MotionEvents.sendUp(uiController, res.down)) {
+                    MotionEvents.sendCancel(uiController, res.down);
+                    return Tapper.Status.FAILURE;
+                }
+            } finally {
+                res.down.recycle();
+            }
+            return res.longPress ? Tapper.Status.WARNING : Tapper.Status.SUCCESS;
+        }
+    };
+
+    public MouseClickAction(Tapper tapper, CoordinatesProvider coordinatesProvider) {
         mGeneralClickAction = new GeneralClickAction(tapper, coordinatesProvider,
-                precisionDescriber);
+                Press.PINPOINT);
     }
 
     @Override
@@ -51,5 +103,13 @@
     @Override
     public void perform(UiController uiController, View view) {
         mGeneralClickAction.perform(new MouseUiController(uiController), view);
+        long doubleTapTimeout = ViewConfiguration.getDoubleTapTimeout();
+        if (0 < doubleTapTimeout) {
+            // Wait to avoid false gesture detection. Without this wait, consecutive clicks can be
+            // detected as a triple click. e.g. 2 double clicks are detected as a triple click and
+            // a single click because espresso isn't aware of triple click detection logic, which
+            // is TextView specific gesture.
+            uiController.loopMainThreadForAtLeast(doubleTapTimeout);
+        }
     }
 }
diff --git a/core/tests/coretests/src/android/widget/espresso/TextViewActions.java b/core/tests/coretests/src/android/widget/espresso/TextViewActions.java
index 32cc6d6..54d5823 100644
--- a/core/tests/coretests/src/android/widget/espresso/TextViewActions.java
+++ b/core/tests/coretests/src/android/widget/espresso/TextViewActions.java
@@ -64,7 +64,7 @@
      */
     public static ViewAction mouseClickOnTextAtIndex(int index) {
         return actionWithAssertions(
-                new MouseClickAction(Tap.SINGLE, new TextCoordinates(index), Press.PINPOINT));
+                new MouseClickAction(Tap.SINGLE, new TextCoordinates(index)));
     }
 
     /**
@@ -94,7 +94,7 @@
      */
     public static ViewAction mouseDoubleClickOnTextAtIndex(int index) {
         return actionWithAssertions(
-                new MouseClickAction(Tap.DOUBLE, new TextCoordinates(index), Press.PINPOINT));
+                new MouseClickAction(Tap.DOUBLE, new TextCoordinates(index)));
     }
 
     /**
@@ -124,7 +124,22 @@
      */
     public static ViewAction mouseLongClickOnTextAtIndex(int index) {
         return actionWithAssertions(
-                new MouseClickAction(Tap.LONG, new TextCoordinates(index), Press.PINPOINT));
+                new MouseClickAction(Tap.LONG, new TextCoordinates(index)));
+    }
+
+    /**
+     * Returns an action that triple-clicks by mouse on text at an index on the TextView.<br>
+     * <br>
+     * View constraints:
+     * <ul>
+     * <li>must be a TextView displayed on screen
+     * <ul>
+     *
+     * @param index The index of the TextView's text to triple-click on.
+     */
+    public static ViewAction mouseTripleClickOnTextAtIndex(int index) {
+        return actionWithAssertions(
+                new MouseClickAction(MouseClickAction.CLICK.TRIPLE, new TextCoordinates(index)));
     }
 
     /**
@@ -237,6 +252,28 @@
                         TextView.class));
     }
 
+    /**
+    * Returns an action that triple click then drags by mouse on text from startIndex to endIndex
+    * on the TextView.<br>
+    * <br>
+    * View constraints:
+    * <ul>
+    * <li>must be a TextView displayed on screen
+    * <ul>
+    *
+    * @param startIndex The index of the TextView's text to start a drag from
+    * @param endIndex The index of the TextView's text to end the drag at
+    */
+   public static ViewAction mouseTripleClickAndDragOnText(int startIndex, int endIndex) {
+       return actionWithAssertions(
+               new DragAction(
+                       DragAction.Drag.MOUSE_TRIPLE_CLICK,
+                       new TextCoordinates(startIndex),
+                       new TextCoordinates(endIndex),
+                       Press.PINPOINT,
+                       TextView.class));
+   }
+
     public enum Handle {
         SELECTION_START,
         SELECTION_END,
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 51019cc..b4f88c33 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -106,6 +106,7 @@
     </permission>
 
     <permission name="android.permission.ACCESS_FM_RADIO" >
+        <!-- /dev/fm is gid media, not audio -->
         <group gid="media" />
     </permission>
 
@@ -128,6 +129,12 @@
     <assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="media" />
     <assign-permission name="android.permission.GET_PROCESS_STATE_AND_OOM_SCORE" uid="media" />
 
+    <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="audioserver" />
+    <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="audioserver" />
+    <assign-permission name="android.permission.WAKE_LOCK" uid="audioserver" />
+    <assign-permission name="android.permission.UPDATE_DEVICE_STATS" uid="audioserver" />
+    <assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="audioserver" />
+
     <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="graphics" />
 
     <!-- This is a list of all the libraries available for application
diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk
index 3181017..d2bd106 100644
--- a/data/fonts/Android.mk
+++ b/data/fonts/Android.mk
@@ -17,11 +17,6 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# Use full Noto Sans Japanese font on non-smaller footprints
-ifneq ($(SMALLER_FONT_FOOTPRINT),true)
-FONT_NOTOSANS_JP_FULL := true
-endif
-
 ##########################################
 # create symlink for given font
 # $(1): new font $(2): link target
@@ -52,24 +47,6 @@
     DroidSans-Bold.ttf
 
 ################################
-# Do not include Motoya on space-constrained devices
-ifneq ($(SMALLER_FONT_FOOTPRINT),true)
-# Do not include Motoya if we are including Noto Sans Japanese
-ifneq ($(FONT_NOTOSANS_JP_FULL),true)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := MTLmr3m.ttf
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT)/fonts
-include $(BUILD_PREBUILT)
-extra_font_files += MTLmr3m.ttf
-
-endif  # !FONT_NOTOSANS_JP_FULL
-endif  # !SMALLER_FONT_FOOTPRINT
-
-################################
 # Use DroidSansMono to hang extra_font_files on
 include $(CLEAR_VARS)
 LOCAL_MODULE := DroidSansMono.ttf
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index 1b97b65..679a6a5 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -330,29 +330,26 @@
         <font weight="400" style="normal">NotoSansSymbols-Regular-Subsetted.ttf</font>
     </family>
     <family lang="zh-Hans">
-        <font weight="400" style="normal">NotoSansSC-Regular.otf</font>
+        <font weight="400" style="normal" ttcIndex="2">NotoSansCJK-Regular.ttc</font>
     </family>
     <family lang="zh-Hant">
-        <font weight="400" style="normal">NotoSansTC-Regular.otf</font>
+        <font weight="400" style="normal" ttcIndex="3">NotoSansCJK-Regular.ttc</font>
     </family>
     <family lang="ja">
-        <font weight="400" style="normal">NotoSansJP-Regular.otf</font>
+        <font weight="400" style="normal" ttcIndex="0">NotoSansCJK-Regular.ttc</font>
     </family>
     <family lang="ko">
-        <font weight="400" style="normal">NotoSansKR-Regular.otf</font>
+        <font weight="400" style="normal" ttcIndex="1">NotoSansCJK-Regular.ttc</font>
     </family>
     <family>
         <font weight="400" style="normal">NanumGothic.ttf</font>
     </family>
-    <family>
+    <family lang="und-Qaae">
         <font weight="400" style="normal">NotoColorEmoji.ttf</font>
     </family>
     <family>
         <font weight="400" style="normal">DroidSansFallback.ttf</font>
     </family>
-    <family lang="ja">
-        <font weight="400" style="normal">MTLmr3m.ttf</font>
-    </family>
     <!--
         Tai Le and Mongolian are intentionally kept last, to make sure they don't override
         the East Asian punctuation for Chinese.
diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java
index b8b7e76..6309ed3 100644
--- a/graphics/java/android/graphics/FontFamily.java
+++ b/graphics/java/android/graphics/FontFamily.java
@@ -58,12 +58,12 @@
         }
     }
 
-    public boolean addFont(String path) {
-        return nAddFont(mNativePtr, path);
+    public boolean addFont(String path, int ttcIndex) {
+        return nAddFont(mNativePtr, path, ttcIndex);
     }
 
-    public boolean addFontWeightStyle(String path, int weight, boolean style) {
-        return nAddFontWeightStyle(mNativePtr, path, weight, style);
+    public boolean addFontWeightStyle(String path, int ttcIndex, int weight, boolean style) {
+        return nAddFontWeightStyle(mNativePtr, path, ttcIndex, weight, style);
     }
 
     public boolean addFontFromAsset(AssetManager mgr, String path) {
@@ -72,9 +72,9 @@
 
     private static native long nCreateFamily(String lang, int variant);
     private static native void nUnrefFamily(long nativePtr);
-    private static native boolean nAddFont(long nativeFamily, String path);
+    private static native boolean nAddFont(long nativeFamily, String path, int ttcIndex);
     private static native boolean nAddFontWeightStyle(long nativeFamily, String path,
-            int weight, boolean isItalic);
+            int ttcIndex, int weight, boolean isItalic);
     private static native boolean nAddFontFromAsset(long nativeFamily, AssetManager mgr,
             String path);
 }
diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java
index 97081f9..2596f53 100644
--- a/graphics/java/android/graphics/FontListParser.java
+++ b/graphics/java/android/graphics/FontListParser.java
@@ -43,12 +43,14 @@
     }
 
     public static class Font {
-        Font(String fontName, int weight, boolean isItalic) {
+        Font(String fontName, int ttcIndex, int weight, boolean isItalic) {
             this.fontName = fontName;
+            this.ttcIndex = ttcIndex;
             this.weight = weight;
             this.isItalic = isItalic;
         }
         public String fontName;
+        public int ttcIndex;
         public int weight;
         public boolean isItalic;
     }
@@ -112,12 +114,14 @@
             if (parser.getEventType() != XmlPullParser.START_TAG) continue;
             String tag = parser.getName();
             if (tag.equals("font")) {
+                String ttcIndexStr = parser.getAttributeValue(null, "ttcIndex");
+                int ttcIndex = ttcIndexStr == null ? 0 : Integer.parseInt(ttcIndexStr);
                 String weightStr = parser.getAttributeValue(null, "weight");
                 int weight = weightStr == null ? 400 : Integer.parseInt(weightStr);
                 boolean isItalic = "italic".equals(parser.getAttributeValue(null, "style"));
                 String filename = parser.nextText();
                 String fullFilename = "/system/fonts/" + filename;
-                fonts.add(new Font(fullFilename, weight, isItalic));
+                fonts.add(new Font(fullFilename, ttcIndex, weight, isItalic));
             } else {
                 skip(parser);
             }
diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java
index 7aa0aef..a226e85 100644
--- a/graphics/java/android/graphics/ImageFormat.java
+++ b/graphics/java/android/graphics/ImageFormat.java
@@ -361,6 +361,17 @@
     public static final int RAW_SENSOR = 0x20;
 
     /**
+     * <p>Private raw camera sensor image format, a single channel image with
+     * implementation depedent pixel layout.</p>
+     *
+     * <p>RAW_PRIVATE is a format for unprocessed raw image buffers coming from an
+     * image sensor. The actual structure of buffers of this format is
+     * implementation-dependent.</p>
+     *
+     */
+    public static final int RAW_PRIVATE = 0x24;
+
+    /**
      * <p>
      * Android 10-bit raw format
      * </p>
@@ -748,6 +759,7 @@
             case FLEX_RGB_888:
             case FLEX_RGBA_8888:
             case RAW_SENSOR:
+            case RAW_PRIVATE:
             case RAW10:
             case RAW12:
             case DEPTH16:
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 35182f9..90522f7 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -25,6 +25,9 @@
 import android.text.TextUtils;
 import android.util.LocaleList;
 
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.HashMap;
 import java.util.Locale;
 
 /**
@@ -56,6 +59,16 @@
     private LocaleList  mLocales;
     private String      mFontFeatureSettings;
 
+    private static final Object sCacheLock = new Object();
+
+    /**
+     * Cache for the Minikin language list ID.
+     *
+     * A map from a string representation of the LocaleList to Minikin's language list ID.
+     */
+    @GuardedBy("sCacheLock")
+    private static final HashMap<String, Integer> sMinikinLangListIdCache = new HashMap<>();
+
     /**
      * @hide
      */
@@ -1335,7 +1348,7 @@
             return;
         }
         mLocales = new LocaleList(locale);
-        nSetTextLocales(mNativePaint, locale.toString());
+        syncTextLocalesWithMinikin();
     }
 
     /**
@@ -1372,7 +1385,21 @@
         }
         if (locales.equals(mLocales)) return;
         mLocales = locales;
-        nSetTextLocales(mNativePaint, locales.toLanguageTags());
+        syncTextLocalesWithMinikin();
+    }
+
+    private void syncTextLocalesWithMinikin() {
+        final String languageTags = mLocales.toLanguageTags();
+        final Integer minikinLangListId;
+        synchronized (sCacheLock) {
+            minikinLangListId = sMinikinLangListIdCache.get(languageTags);
+            if (minikinLangListId == null) {
+                final int newID = nSetTextLocales(mNativePaint, languageTags);
+                sMinikinLangListIdCache.put(languageTags, newID);
+                return;
+            }
+        }
+        nSetTextLocalesByMinikinLangListId(mNativePaint, minikinLangListId.intValue());
     }
 
     /**
@@ -2714,8 +2741,9 @@
     private static native void nSetTextAlign(long paintPtr,
                                                    int align);
 
-    private static native void nSetTextLocales(long paintPtr,
-                                                    String locales);
+    private static native int nSetTextLocales(long paintPtr, String locales);
+    private static native void nSetTextLocalesByMinikinLangListId(long paintPtr,
+            int mMinikinLangListId);
 
     private static native float nGetTextAdvances(long paintPtr, long typefacePtr,
             char[] text, int index, int count, int contextIndex, int contextCount,
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 7eb5584..1294323 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -209,7 +209,7 @@
     public static Typeface createFromFile(String path) {
         if (sFallbackFonts != null) {
             FontFamily fontFamily = new FontFamily();
-            if (fontFamily.addFont(path)) {
+            if (fontFamily.addFont(path, 0 /* ttcIndex */)) {
                 FontFamily[] families = { fontFamily };
                 return createFromFamiliesWithDefault(families);
             }
@@ -262,7 +262,7 @@
     private static FontFamily makeFamilyFromParsed(FontListParser.Family family) {
         FontFamily fontFamily = new FontFamily(family.lang, family.variant);
         for (FontListParser.Font font : family.fonts) {
-            fontFamily.addFontWeightStyle(font.fontName, font.weight, font.isItalic);
+            fontFamily.addFontWeightStyle(font.fontName, font.ttcIndex, font.weight, font.isItalic);
         }
         return fontFamily;
     }
diff --git a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
index 971a3a2..d714ca8 100644
--- a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
@@ -153,7 +153,7 @@
                 updateStateFromTypedArray(a);
                 verifyRequiredAttributes(a);
             } catch (XmlPullParserException e) {
-                throw new RuntimeException(e);
+                rethrowAsRuntimeException(e);
             } finally {
                 a.recycle();
             }
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 4d2037b..daf2581 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -829,7 +829,7 @@
             try {
                 updateStateFromTypedArray(a);
             } catch (XmlPullParserException e) {
-                throw new RuntimeException(e);
+                rethrowAsRuntimeException(e);
             } finally {
                 a.recycle();
             }
diff --git a/graphics/java/android/graphics/drawable/ClipDrawable.java b/graphics/java/android/graphics/drawable/ClipDrawable.java
index cdd336d..d925b6b 100644
--- a/graphics/java/android/graphics/drawable/ClipDrawable.java
+++ b/graphics/java/android/graphics/drawable/ClipDrawable.java
@@ -111,7 +111,7 @@
                 updateStateFromTypedArray(a);
                 verifyRequiredAttributes(a);
             } catch (XmlPullParserException e) {
-                throw new RuntimeException(e);
+                rethrowAsRuntimeException(e);
             } finally {
                 a.recycle();
             }
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 0ee877e..3d8437d 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -1430,6 +1430,20 @@
     }
 
     /**
+     * Re-throws an exception as a {@link RuntimeException} with an empty stack
+     * trace to avoid cluttering the log. The original exception's stack trace
+     * will still be included.
+     *
+     * @param cause the exception to re-throw
+     * @throws RuntimeException
+     */
+    static void rethrowAsRuntimeException(Exception cause) throws RuntimeException {
+        final RuntimeException e = new RuntimeException(cause);
+        e.setStackTrace(new StackTraceElement[0]);
+        throw e;
+    }
+
+    /**
      * Parses a {@link android.graphics.PorterDuff.Mode} from a tintMode
      * attribute's enum value.
      *
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 4be86ef..f9208cd 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -23,7 +23,6 @@
 import android.content.res.Resources;
 import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
-import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.ColorFilter;
@@ -1268,7 +1267,7 @@
             try {
                 updateGradientDrawableGradient(t.getResources(), a);
             } catch (XmlPullParserException e) {
-                throw new RuntimeException(e);
+                rethrowAsRuntimeException(e);
             } finally {
                 a.recycle();
             }
@@ -1636,8 +1635,14 @@
     public void getOutline(Outline outline) {
         final GradientState st = mGradientState;
         final Rect bounds = getBounds();
-        // only report non-zero alpha if shape being drawn is opaque
-        outline.setAlpha(st.mOpaqueOverShape && isOpaqueForState() ? (mAlpha / 255.0f) : 0.0f);
+        // only report non-zero alpha if shape being drawn has consistent opacity over shape. Must
+        // either not have a stroke, or have same stroke/fill opacity
+        boolean useFillOpacity = st.mOpaqueOverShape && (mGradientState.mStrokeWidth <= 0
+                || mStrokePaint == null
+                || mStrokePaint.getAlpha() == mFillPaint.getAlpha());
+        outline.setAlpha(useFillOpacity
+                ? modulateAlpha(mFillPaint.getAlpha()) / 255.0f
+                : 0.0f);
 
         switch (st.mShape) {
             case RECTANGLE:
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index d800acb..0de4c2c 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -44,6 +44,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.Objects;
 
 /**
  * An umbrella container for several serializable graphics representations, including Bitmaps,
@@ -459,6 +460,37 @@
     }
 
     /**
+     * Compares if this icon is constructed from the same resources as another icon.
+     * Note that this is an inexpensive operation and doesn't do deep Bitmap equality comparisons.
+     *
+     * @param otherIcon the other icon
+     * @return whether this icon is the same as the another one
+     * @hide
+     */
+    public boolean sameAs(Icon otherIcon) {
+        if (otherIcon == this) {
+            return true;
+        }
+        if (mType != otherIcon.getType()) {
+            return false;
+        }
+        switch (mType) {
+            case TYPE_BITMAP:
+                return getBitmap() == otherIcon.getBitmap();
+            case TYPE_DATA:
+                return getDataLength() == otherIcon.getDataLength()
+                        && getDataOffset() == otherIcon.getDataOffset()
+                        && getDataBytes() == otherIcon.getDataBytes();
+            case TYPE_RESOURCE:
+                return getResId() == otherIcon.getResId()
+                        && Objects.equals(getResPackage(), otherIcon.getResPackage());
+            case TYPE_URI:
+                return Objects.equals(getUriString(), otherIcon.getUriString());
+        }
+        return false;
+    }
+
+    /**
      * Create an Icon pointing to a drawable resource.
      * @param context The context for the application whose resources should be used to resolve the
      *                given resource ID.
diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java
index 36d4272..d47cb56 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -124,7 +124,7 @@
                 updateStateFromTypedArray(a);
                 verifyRequiredAttributes(a);
             } catch (XmlPullParserException e) {
-                throw new RuntimeException(e);
+                rethrowAsRuntimeException(e);
             } finally {
                 a.recycle();
             }
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 4d51d63..bfbdfa5 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -510,7 +510,7 @@
             try {
                 updateStateFromTypedArray(a);
             } catch (XmlPullParserException e) {
-                throw new RuntimeException(e);
+                rethrowAsRuntimeException(e);
             } finally {
                 a.recycle();
             }
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index aaab529..5213e10 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -40,7 +40,6 @@
 import android.graphics.Rect;
 import android.graphics.Shader;
 import android.util.AttributeSet;
-import android.util.DisplayMetrics;
 
 import java.io.IOException;
 import java.util.Arrays;
@@ -505,7 +504,7 @@
                 updateStateFromTypedArray(a);
                 verifyRequiredAttributes(a);
             } catch (XmlPullParserException e) {
-                throw new RuntimeException(e);
+                rethrowAsRuntimeException(e);
             } finally {
                 a.recycle();
             }
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index 1531ba2..78424e3 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -92,7 +92,7 @@
                 updateStateFromTypedArray(a);
                 verifyRequiredAttributes(a);
             } catch (XmlPullParserException e) {
-                throw new RuntimeException(e);
+                rethrowAsRuntimeException(e);
             } finally {
                 a.recycle();
             }
diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java
index 330266f..51e143b 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -125,7 +125,7 @@
                 updateStateFromTypedArray(a);
                 verifyRequiredAttributes(a);
             } catch (XmlPullParserException e) {
-                throw new RuntimeException(e);
+                rethrowAsRuntimeException(e);
             } finally {
                 a.recycle();
             }
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index f630055e..3761a99 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -511,7 +511,7 @@
                 state.mCacheDirty = true;
                 updateStateFromTypedArray(a);
             } catch (XmlPullParserException e) {
-                throw new RuntimeException(e);
+                rethrowAsRuntimeException(e);
             } finally {
                 a.recycle();
             }
diff --git a/include/android_runtime/android_view_Surface.h b/include/android_runtime/android_view_Surface.h
index ed83314..b1e552a 100644
--- a/include/android_runtime/android_view_Surface.h
+++ b/include/android_runtime/android_view_Surface.h
@@ -45,7 +45,9 @@
     RAW_SENSOR        = 0x20,
     PRIVATE           = 0x22,
     YUV_420_888       = 0x23,
+    RAW_PRIVATE       = 0x24,
     RAW10             = 0x25,
+    RAW12             = 0x26,
     JPEG              = 0x100,
     DEPTH_POINT_CLOUD = 0x101,
     YV12              = 0x32315659,
diff --git a/keystore/java/android/security/IKeyChainService.aidl b/keystore/java/android/security/IKeyChainService.aidl
index 20c94c5..cfcb4e0 100644
--- a/keystore/java/android/security/IKeyChainService.aidl
+++ b/keystore/java/android/security/IKeyChainService.aidl
@@ -33,6 +33,7 @@
 
     // APIs used by DevicePolicyManager
     boolean installKeyPair(in byte[] privateKey, in byte[] userCert, String alias);
+    boolean removeKeyPair(String alias);
 
     // APIs used by Settings
     boolean deleteCaCertificate(String alias);
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index d98497b..0d1ee46 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -90,6 +90,9 @@
     protos/hwui.proto
 
 hwui_test_common_src_files := \
+    $(call all-cpp-files-under, tests/common/scenes) \
+    tests/common/TestContext.cpp \
+    tests/common/TestScene.cpp \
     tests/common/TestUtils.cpp
 
 hwui_cflags := \
@@ -259,12 +262,9 @@
 
 LOCAL_SRC_FILES += \
     $(hwui_test_common_src_files) \
-    tests/macrobench/TestContext.cpp \
     tests/macrobench/TestSceneRunner.cpp \
     tests/macrobench/main.cpp
 
-LOCAL_SRC_FILES += $(call all-cpp-files-under, tests/common/scenes)
-
 include $(BUILD_EXECUTABLE)
 
 # ------------------------
diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp
index 7e09699..41411a9 100644
--- a/libs/hwui/AssetAtlas.cpp
+++ b/libs/hwui/AssetAtlas.cpp
@@ -79,13 +79,13 @@
 // Entries
 ///////////////////////////////////////////////////////////////////////////////
 
-AssetAtlas::Entry* AssetAtlas::getEntry(const SkBitmap* bitmap) const {
-    ssize_t index = mEntries.indexOfKey(bitmap->pixelRef());
+AssetAtlas::Entry* AssetAtlas::getEntry(const SkPixelRef* pixelRef) const {
+    ssize_t index = mEntries.indexOfKey(pixelRef);
     return index >= 0 ? mEntries.valueAt(index) : nullptr;
 }
 
-Texture* AssetAtlas::getEntryTexture(const SkBitmap* bitmap) const {
-    ssize_t index = mEntries.indexOfKey(bitmap->pixelRef());
+Texture* AssetAtlas::getEntryTexture(const SkPixelRef* pixelRef) const {
+    ssize_t index = mEntries.indexOfKey(pixelRef);
     return index >= 0 ? mEntries.valueAt(index)->texture : nullptr;
 }
 
diff --git a/libs/hwui/AssetAtlas.h b/libs/hwui/AssetAtlas.h
index f1cd0b4..a037725 100644
--- a/libs/hwui/AssetAtlas.h
+++ b/libs/hwui/AssetAtlas.h
@@ -148,15 +148,15 @@
 
     /**
      * Returns the entry in the atlas associated with the specified
-     * bitmap. If the bitmap is not in the atlas, return NULL.
+     * pixelRef. If the pixelRef is not in the atlas, return NULL.
      */
-    Entry* getEntry(const SkBitmap* bitmap) const;
+    Entry* getEntry(const SkPixelRef* pixelRef) const;
 
     /**
      * Returns the texture for the atlas entry associated with the
-     * specified bitmap. If the bitmap is not in the atlas, return NULL.
+     * specified pixelRef. If the pixelRef is not in the atlas, return NULL.
      */
-    Texture* getEntryTexture(const SkBitmap* bitmap) const;
+    Texture* getEntryTexture(const SkPixelRef* pixelRef) const;
 
 private:
     void createEntries(Caches& caches, int64_t* map, int count);
diff --git a/libs/hwui/BakedOpDispatcher.cpp b/libs/hwui/BakedOpDispatcher.cpp
index b56b1e4..d4dbb00 100644
--- a/libs/hwui/BakedOpDispatcher.cpp
+++ b/libs/hwui/BakedOpDispatcher.cpp
@@ -20,6 +20,8 @@
 #include "Caches.h"
 #include "Glop.h"
 #include "GlopBuilder.h"
+#include "Patch.h"
+#include "PathTessellator.h"
 #include "renderstate/OffscreenBufferPool.h"
 #include "renderstate/RenderState.h"
 #include "utils/GLUtils.h"
@@ -27,24 +29,379 @@
 
 #include <algorithm>
 #include <math.h>
+#include <SkPaintDefaults.h>
 
 namespace android {
 namespace uirenderer {
 
+static void storeTexturedRect(TextureVertex* vertices, const Rect& bounds, const Rect& texCoord) {
+    vertices[0] = { bounds.left, bounds.top, texCoord.left, texCoord.top };
+    vertices[1] = { bounds.right, bounds.top, texCoord.right, texCoord.top };
+    vertices[2] = { bounds.left, bounds.bottom, texCoord.left, texCoord.bottom };
+    vertices[3] = { bounds.right, bounds.bottom, texCoord.right, texCoord.bottom };
+}
+
+void BakedOpDispatcher::onMergedBitmapOps(BakedOpRenderer& renderer,
+        const MergedBakedOpList& opList) {
+
+    const BakedOpState& firstState = *(opList.states[0]);
+    const SkBitmap* bitmap = (static_cast<const BitmapOp*>(opList.states[0]->op))->bitmap;
+
+    AssetAtlas::Entry* entry = renderer.renderState().assetAtlas().getEntry(bitmap->pixelRef());
+    Texture* texture = entry ? entry->texture : renderer.caches().textureCache.get(bitmap);
+    if (!texture) return;
+    const AutoTexture autoCleanup(texture);
+
+    TextureVertex vertices[opList.count * 4];
+    Rect texCoords(0, 0, 1, 1);
+    if (entry) {
+        entry->uvMapper.map(texCoords);
+    }
+    for (size_t i = 0; i < opList.count; i++) {
+        const BakedOpState& state = *(opList.states[i]);
+        TextureVertex* rectVerts = &vertices[i * 4];
+        Rect opBounds = state.computedState.clippedBounds;
+        if (CC_LIKELY(state.computedState.transform.isPureTranslate())) {
+            // pure translate, so snap (same behavior as onBitmapOp)
+            opBounds.snapToPixelBoundaries();
+        }
+        storeTexturedRect(rectVerts, opBounds, texCoords);
+        renderer.dirtyRenderTarget(opBounds);
+    }
+
+    const int textureFillFlags = (bitmap->colorType() == kAlpha_8_SkColorType)
+            ? TextureFillFlags::IsAlphaMaskTexture : TextureFillFlags::None;
+    Glop glop;
+    GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
+            .setRoundRectClipState(firstState.roundRectClipState)
+            .setMeshTexturedIndexedQuads(vertices, opList.count * 6)
+            .setFillTexturePaint(*texture, textureFillFlags, firstState.op->paint, firstState.alpha)
+            .setTransform(Matrix4::identity(), TransformFlags::None)
+            .setModelViewIdentityEmptyBounds()
+            .build();
+    renderer.renderGlop(nullptr, opList.clipSideFlags ? &opList.clip : nullptr, glop);
+}
+
+void BakedOpDispatcher::onMergedPatchOps(BakedOpRenderer& renderer,
+        const MergedBakedOpList& opList) {
+    const PatchOp& firstOp = *(static_cast<const PatchOp*>(opList.states[0]->op));
+    const BakedOpState& firstState = *(opList.states[0]);
+    AssetAtlas::Entry* entry = renderer.renderState().assetAtlas().getEntry(
+            firstOp.bitmap->pixelRef());
+
+    // Batches will usually contain a small number of items so it's
+    // worth performing a first iteration to count the exact number
+    // of vertices we need in the new mesh
+    uint32_t totalVertices = 0;
+
+    for (size_t i = 0; i < opList.count; i++) {
+        const PatchOp& op = *(static_cast<const PatchOp*>(opList.states[i]->op));
+
+        // TODO: cache mesh lookups
+        const Patch* opMesh = renderer.caches().patchCache.get(
+                entry, op.bitmap->width(), op.bitmap->height(),
+                op.unmappedBounds.getWidth(), op.unmappedBounds.getHeight(), op.patch);
+        totalVertices += opMesh->verticesCount;
+    }
+
+    const bool dirtyRenderTarget = renderer.offscreenRenderTarget();
+
+    uint32_t indexCount = 0;
+
+    TextureVertex vertices[totalVertices];
+    TextureVertex* vertex = &vertices[0];
+    // Create a mesh that contains the transformed vertices for all the
+    // 9-patch objects that are part of the batch. Note that onDefer()
+    // enforces ops drawn by this function to have a pure translate or
+    // identity matrix
+    for (size_t i = 0; i < opList.count; i++) {
+        const PatchOp& op = *(static_cast<const PatchOp*>(opList.states[i]->op));
+        const BakedOpState& state = *opList.states[i];
+
+        // TODO: cache mesh lookups
+        const Patch* opMesh = renderer.caches().patchCache.get(
+                entry, op.bitmap->width(), op.bitmap->height(),
+                op.unmappedBounds.getWidth(), op.unmappedBounds.getHeight(), op.patch);
+
+
+        uint32_t vertexCount = opMesh->verticesCount;
+        if (vertexCount == 0) continue;
+
+        // We use the bounds to know where to translate our vertices
+        // Using patchOp->state.mBounds wouldn't work because these
+        // bounds are clipped
+        const float tx = floorf(state.computedState.transform.getTranslateX()
+                + op.unmappedBounds.left + 0.5f);
+        const float ty = floorf(state.computedState.transform.getTranslateY()
+                + op.unmappedBounds.top + 0.5f);
+
+        // Copy & transform all the vertices for the current operation
+        TextureVertex* opVertices = opMesh->vertices.get();
+        for (uint32_t j = 0; j < vertexCount; j++, opVertices++) {
+            TextureVertex::set(vertex++,
+                    opVertices->x + tx, opVertices->y + ty,
+                    opVertices->u, opVertices->v);
+        }
+
+        // Dirty the current layer if possible. When the 9-patch does not
+        // contain empty quads we can take a shortcut and simply set the
+        // dirty rect to the object's bounds.
+        if (dirtyRenderTarget) {
+            if (!opMesh->hasEmptyQuads) {
+                renderer.dirtyRenderTarget(Rect(tx, ty,
+                        tx + op.unmappedBounds.getWidth(), ty + op.unmappedBounds.getHeight()));
+            } else {
+                const size_t count = opMesh->quads.size();
+                for (size_t i = 0; i < count; i++) {
+                    const Rect& quadBounds = opMesh->quads[i];
+                    const float x = tx + quadBounds.left;
+                    const float y = ty + quadBounds.top;
+                    renderer.dirtyRenderTarget(Rect(x, y,
+                            x + quadBounds.getWidth(), y + quadBounds.getHeight()));
+                }
+            }
+        }
+
+        indexCount += opMesh->indexCount;
+    }
+
+
+    Texture* texture = entry ? entry->texture : renderer.caches().textureCache.get(firstOp.bitmap);
+    if (!texture) return;
+    const AutoTexture autoCleanup(texture);
+
+    // 9 patches are built for stretching - always filter
+    int textureFillFlags = TextureFillFlags::ForceFilter;
+    if (firstOp.bitmap->colorType() == kAlpha_8_SkColorType) {
+        textureFillFlags |= TextureFillFlags::IsAlphaMaskTexture;
+    }
+    Glop glop;
+    GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
+            .setRoundRectClipState(firstState.roundRectClipState)
+            .setMeshTexturedIndexedQuads(vertices, indexCount)
+            .setFillTexturePaint(*texture, textureFillFlags, firstOp.paint, firstState.alpha)
+            .setTransform(Matrix4::identity(), TransformFlags::None)
+            .setModelViewIdentityEmptyBounds()
+            .build();
+    renderer.renderGlop(nullptr, opList.clipSideFlags ? &opList.clip : nullptr, glop);
+}
+
+static void renderTextShadow(BakedOpRenderer& renderer, FontRenderer& fontRenderer,
+        const TextOp& op, const BakedOpState& state) {
+    renderer.caches().textureState().activateTexture(0);
+
+    PaintUtils::TextShadow textShadow;
+    if (!PaintUtils::getTextShadow(op.paint, &textShadow)) {
+        LOG_ALWAYS_FATAL("failed to query shadow attributes");
+    }
+
+    renderer.caches().dropShadowCache.setFontRenderer(fontRenderer);
+    ShadowTexture* texture = renderer.caches().dropShadowCache.get(
+            op.paint, (const char*) op.glyphs,
+            op.glyphCount, textShadow.radius, op.positions);
+    // If the drop shadow exceeds the max texture size or couldn't be
+    // allocated, skip drawing
+    if (!texture) return;
+    const AutoTexture autoCleanup(texture);
+
+    const float sx = op.x - texture->left + textShadow.dx;
+    const float sy = op.y - texture->top + textShadow.dy;
+
+    Glop glop;
+    GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
+            .setRoundRectClipState(state.roundRectClipState)
+            .setMeshTexturedUnitQuad(nullptr)
+            .setFillShadowTexturePaint(*texture, textShadow.color, *op.paint, state.alpha)
+            .setTransform(state.computedState.transform, TransformFlags::None)
+            .setModelViewMapUnitToRect(Rect(sx, sy, sx + texture->width, sy + texture->height))
+            .build();
+    renderer.renderGlop(state, glop);
+}
+
+enum class TextRenderType {
+    Defer,
+    Flush
+};
+
+static void renderTextOp(BakedOpRenderer& renderer, const TextOp& op, const BakedOpState& state,
+        const Rect* renderClip, TextRenderType renderType) {
+    FontRenderer& fontRenderer = renderer.caches().fontRenderer.getFontRenderer();
+
+    if (CC_UNLIKELY(PaintUtils::hasTextShadow(op.paint))) {
+        fontRenderer.setFont(op.paint, SkMatrix::I());
+        renderTextShadow(renderer, fontRenderer, op, state);
+    }
+
+    float x = op.x;
+    float y = op.y;
+    const Matrix4& transform = state.computedState.transform;
+    const bool pureTranslate = transform.isPureTranslate();
+    if (CC_LIKELY(pureTranslate)) {
+        x = floorf(x + transform.getTranslateX() + 0.5f);
+        y = floorf(y + transform.getTranslateY() + 0.5f);
+        fontRenderer.setFont(op.paint, SkMatrix::I());
+        fontRenderer.setTextureFiltering(false);
+    } else if (CC_UNLIKELY(transform.isPerspective())) {
+        fontRenderer.setFont(op.paint, SkMatrix::I());
+        fontRenderer.setTextureFiltering(true);
+    } else {
+        // We only pass a partial transform to the font renderer. That partial
+        // matrix defines how glyphs are rasterized. Typically we want glyphs
+        // to be rasterized at their final size on screen, which means the partial
+        // matrix needs to take the scale factor into account.
+        // When a partial matrix is used to transform glyphs during rasterization,
+        // the mesh is generated with the inverse transform (in the case of scale,
+        // the mesh is generated at 1.0 / scale for instance.) This allows us to
+        // apply the full transform matrix at draw time in the vertex shader.
+        // Applying the full matrix in the shader is the easiest way to handle
+        // rotation and perspective and allows us to always generated quads in the
+        // font renderer which greatly simplifies the code, clipping in particular.
+        float sx, sy;
+        transform.decomposeScale(sx, sy);
+        fontRenderer.setFont(op.paint, SkMatrix::MakeScale(
+                roundf(std::max(1.0f, sx)),
+                roundf(std::max(1.0f, sy))));
+        fontRenderer.setTextureFiltering(true);
+    }
+    Rect layerBounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
+
+    int alpha = PaintUtils::getAlphaDirect(op.paint) * state.alpha;
+    SkXfermode::Mode mode = PaintUtils::getXfermodeDirect(op.paint);
+    TextDrawFunctor functor(&renderer, &state, renderClip,
+            x, y, pureTranslate, alpha, mode, op.paint);
+
+    bool forceFinish = (renderType == TextRenderType::Flush);
+    bool mustDirtyRenderTarget = renderer.offscreenRenderTarget();
+    const Rect* localOpClip = pureTranslate ? &state.computedState.clipRect : nullptr;
+    fontRenderer.renderPosText(op.paint, localOpClip,
+            (const char*) op.glyphs, op.glyphCount, x, y,
+            op.positions, mustDirtyRenderTarget ? &layerBounds : nullptr, &functor, forceFinish);
+
+    if (mustDirtyRenderTarget) {
+        if (!pureTranslate) {
+            transform.mapRect(layerBounds);
+        }
+        renderer.dirtyRenderTarget(layerBounds);
+    }
+}
+
+void BakedOpDispatcher::onMergedTextOps(BakedOpRenderer& renderer,
+        const MergedBakedOpList& opList) {
+    const Rect* clip = opList.clipSideFlags ? &opList.clip : nullptr;
+    for (size_t i = 0; i < opList.count; i++) {
+        const BakedOpState& state = *(opList.states[i]);
+        const TextOp& op = *(static_cast<const TextOp*>(state.op));
+        TextRenderType renderType = (i + 1 == opList.count)
+                ? TextRenderType::Flush : TextRenderType::Defer;
+        renderTextOp(renderer, op, state, clip, renderType);
+    }
+}
+
 void BakedOpDispatcher::onRenderNodeOp(BakedOpRenderer&, const RenderNodeOp&, const BakedOpState&) {
     LOG_ALWAYS_FATAL("unsupported operation");
 }
 
-void BakedOpDispatcher::onBeginLayerOp(BakedOpRenderer& renderer, const BeginLayerOp& op, const BakedOpState& state) {
+void BakedOpDispatcher::onBeginLayerOp(BakedOpRenderer&, const BeginLayerOp&, const BakedOpState&) {
     LOG_ALWAYS_FATAL("unsupported operation");
 }
 
-void BakedOpDispatcher::onEndLayerOp(BakedOpRenderer& renderer, const EndLayerOp& op, const BakedOpState& state) {
+void BakedOpDispatcher::onEndLayerOp(BakedOpRenderer&, const EndLayerOp&, const BakedOpState&) {
     LOG_ALWAYS_FATAL("unsupported operation");
 }
 
+void BakedOpDispatcher::onCirclePropsOp(BakedOpRenderer&, const CirclePropsOp&, const BakedOpState&) {
+    LOG_ALWAYS_FATAL("unsupported operation");
+}
+
+void BakedOpDispatcher::onRoundRectPropsOp(BakedOpRenderer&, const RoundRectPropsOp&, const BakedOpState&) {
+    LOG_ALWAYS_FATAL("unsupported operation");
+}
+
+namespace VertexBufferRenderFlags {
+    enum {
+        Offset = 0x1,
+        ShadowInterp = 0x2,
+    };
+}
+
+static void renderVertexBuffer(BakedOpRenderer& renderer, const BakedOpState& state,
+        const VertexBuffer& vertexBuffer, float translateX, float translateY,
+        const SkPaint& paint, int vertexBufferRenderFlags) {
+    if (CC_LIKELY(vertexBuffer.getVertexCount())) {
+        bool shadowInterp = vertexBufferRenderFlags & VertexBufferRenderFlags::ShadowInterp;
+        const int transformFlags = TransformFlags::OffsetByFudgeFactor;
+        Glop glop;
+        GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
+                .setRoundRectClipState(state.roundRectClipState)
+                .setMeshVertexBuffer(vertexBuffer, shadowInterp)
+                .setFillPaint(paint, state.alpha)
+                .setTransform(state.computedState.transform, transformFlags)
+                .setModelViewOffsetRect(translateX, translateY, vertexBuffer.getBounds())
+                .build();
+        renderer.renderGlop(state, glop);
+    }
+}
+
+static void renderConvexPath(BakedOpRenderer& renderer, const BakedOpState& state,
+        const SkPath& path, const SkPaint& paint) {
+    VertexBuffer vertexBuffer;
+    // TODO: try clipping large paths to viewport
+    PathTessellator::tessellatePath(path, &paint, state.computedState.transform, vertexBuffer);
+    renderVertexBuffer(renderer, state, vertexBuffer, 0.0f, 0.0f, paint, 0);
+}
+
+static void renderPathTexture(BakedOpRenderer& renderer, const BakedOpState& state,
+        PathTexture& texture, const RecordedOp& op) {
+    Rect dest(texture.width, texture.height);
+    dest.translate(texture.left + op.unmappedBounds.left - texture.offset,
+            texture.top + op.unmappedBounds.top - texture.offset);
+    Glop glop;
+    GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
+            .setRoundRectClipState(state.roundRectClipState)
+            .setMeshTexturedUnitQuad(nullptr)
+            .setFillPathTexturePaint(texture, *(op.paint), state.alpha)
+            .setTransform(state.computedState.transform,  TransformFlags::None)
+            .setModelViewMapUnitToRect(dest)
+            .build();
+    renderer.renderGlop(state, glop);
+}
+
+SkRect getBoundsOfFill(const RecordedOp& op) {
+    SkRect bounds = op.unmappedBounds.toSkRect();
+    if (op.paint->getStyle() == SkPaint::kStrokeAndFill_Style) {
+        float outsetDistance = op.paint->getStrokeWidth() / 2;
+        bounds.outset(outsetDistance, outsetDistance);
+    }
+    return bounds;
+}
+
+void BakedOpDispatcher::onArcOp(BakedOpRenderer& renderer, const ArcOp& op, const BakedOpState& state) {
+    // TODO: support fills (accounting for concavity if useCenter && sweepAngle > 180)
+    if (op.paint->getStyle() != SkPaint::kStroke_Style
+            || op.paint->getPathEffect() != nullptr
+            || op.useCenter) {
+        PathTexture* texture = renderer.caches().pathCache.getArc(
+                op.unmappedBounds.getWidth(), op.unmappedBounds.getHeight(),
+                op.startAngle, op.sweepAngle, op.useCenter, op.paint);
+        const AutoTexture holder(texture);
+        if (CC_LIKELY(holder.texture)) {
+            renderPathTexture(renderer, state, *texture, op);
+        }
+    } else {
+        SkRect rect = getBoundsOfFill(op);
+        SkPath path;
+        if (op.useCenter) {
+            path.moveTo(rect.centerX(), rect.centerY());
+        }
+        path.arcTo(rect, op.startAngle, op.sweepAngle, !op.useCenter);
+        if (op.useCenter) {
+            path.close();
+        }
+        renderConvexPath(renderer, state, path, *(op.paint));
+    }
+}
+
 void BakedOpDispatcher::onBitmapOp(BakedOpRenderer& renderer, const BitmapOp& op, const BakedOpState& state) {
-    renderer.caches().textureState().activateTexture(0); // TODO: should this be automatic, and/or elsewhere?
     Texture* texture = renderer.getTexture(op.bitmap);
     if (!texture) return;
     const AutoTexture autoCleanup(texture);
@@ -62,44 +419,230 @@
     renderer.renderGlop(state, glop);
 }
 
-void BakedOpDispatcher::onLinesOp(BakedOpRenderer& renderer, const LinesOp& op, const BakedOpState& state) {
-    LOG_ALWAYS_FATAL("todo");
-}
+void BakedOpDispatcher::onBitmapMeshOp(BakedOpRenderer& renderer, const BitmapMeshOp& op, const BakedOpState& state) {
+    const static UvMapper defaultUvMapper;
+    const uint32_t elementCount = op.meshWidth * op.meshHeight * 6;
 
-void BakedOpDispatcher::onRectOp(BakedOpRenderer& renderer, const RectOp& op, const BakedOpState& state) {
+    std::unique_ptr<ColorTextureVertex[]> mesh(new ColorTextureVertex[elementCount]);
+    ColorTextureVertex* vertex = &mesh[0];
+
+    const int* colors = op.colors;
+    std::unique_ptr<int[]> tempColors;
+    if (!colors) {
+        uint32_t colorsCount = (op.meshWidth + 1) * (op.meshHeight + 1);
+        tempColors.reset(new int[colorsCount]);
+        memset(tempColors.get(), 0xff, colorsCount * sizeof(int));
+        colors = tempColors.get();
+    }
+
+    Texture* texture = renderer.renderState().assetAtlas().getEntryTexture(op.bitmap->pixelRef());
+    const UvMapper& mapper(texture && texture->uvMapper ? *texture->uvMapper : defaultUvMapper);
+
+    for (int32_t y = 0; y < op.meshHeight; y++) {
+        for (int32_t x = 0; x < op.meshWidth; x++) {
+            uint32_t i = (y * (op.meshWidth + 1) + x) * 2;
+
+            float u1 = float(x) / op.meshWidth;
+            float u2 = float(x + 1) / op.meshWidth;
+            float v1 = float(y) / op.meshHeight;
+            float v2 = float(y + 1) / op.meshHeight;
+
+            mapper.map(u1, v1, u2, v2);
+
+            int ax = i + (op.meshWidth + 1) * 2;
+            int ay = ax + 1;
+            int bx = i;
+            int by = bx + 1;
+            int cx = i + 2;
+            int cy = cx + 1;
+            int dx = i + (op.meshWidth + 1) * 2 + 2;
+            int dy = dx + 1;
+
+            const float* vertices = op.vertices;
+            ColorTextureVertex::set(vertex++, vertices[dx], vertices[dy], u2, v2, colors[dx / 2]);
+            ColorTextureVertex::set(vertex++, vertices[ax], vertices[ay], u1, v2, colors[ax / 2]);
+            ColorTextureVertex::set(vertex++, vertices[bx], vertices[by], u1, v1, colors[bx / 2]);
+
+            ColorTextureVertex::set(vertex++, vertices[dx], vertices[dy], u2, v2, colors[dx / 2]);
+            ColorTextureVertex::set(vertex++, vertices[bx], vertices[by], u1, v1, colors[bx / 2]);
+            ColorTextureVertex::set(vertex++, vertices[cx], vertices[cy], u2, v1, colors[cx / 2]);
+        }
+    }
+
+    if (!texture) {
+        texture = renderer.caches().textureCache.get(op.bitmap);
+        if (!texture) {
+            return;
+        }
+    }
+    const AutoTexture autoCleanup(texture);
+
+    /*
+     * TODO: handle alpha_8 textures correctly by applying paint color, but *not*
+     * shader in that case to mimic the behavior in SkiaCanvas::drawBitmapMesh.
+     */
+    const int textureFillFlags = TextureFillFlags::None;
     Glop glop;
     GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
             .setRoundRectClipState(state.roundRectClipState)
-            .setMeshUnitQuad()
-            .setFillPaint(*op.paint, state.alpha)
-            .setTransform(state.computedState.transform, TransformFlags::None)
-            .setModelViewMapUnitToRect(op.unmappedBounds)
+            .setMeshColoredTexturedMesh(mesh.get(), elementCount)
+            .setFillTexturePaint(*texture, textureFillFlags, op.paint, state.alpha)
+            .setTransform(state.computedState.transform,  TransformFlags::None)
+            .setModelViewOffsetRect(0, 0, op.unmappedBounds)
             .build();
     renderer.renderGlop(state, glop);
 }
 
-namespace VertexBufferRenderFlags {
-    enum {
-        Offset = 0x1,
-        ShadowInterp = 0x2,
-    };
+void BakedOpDispatcher::onBitmapRectOp(BakedOpRenderer& renderer, const BitmapRectOp& op, const BakedOpState& state) {
+    Texture* texture = renderer.getTexture(op.bitmap);
+    if (!texture) return;
+    const AutoTexture autoCleanup(texture);
+
+    Rect uv(std::max(0.0f, op.src.left / texture->width),
+            std::max(0.0f, op.src.top / texture->height),
+            std::min(1.0f, op.src.right / texture->width),
+            std::min(1.0f, op.src.bottom / texture->height));
+
+    const int textureFillFlags = (op.bitmap->colorType() == kAlpha_8_SkColorType)
+            ? TextureFillFlags::IsAlphaMaskTexture : TextureFillFlags::None;
+    const bool tryToSnap = MathUtils::areEqual(op.src.getWidth(), op.unmappedBounds.getWidth())
+            && MathUtils::areEqual(op.src.getHeight(), op.unmappedBounds.getHeight());
+    Glop glop;
+    GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
+            .setRoundRectClipState(state.roundRectClipState)
+            .setMeshTexturedUvQuad(texture->uvMapper, uv)
+            .setFillTexturePaint(*texture, textureFillFlags, op.paint, state.alpha)
+            .setTransform(state.computedState.transform, TransformFlags::None)
+            .setModelViewMapUnitToRectOptionalSnap(tryToSnap, op.unmappedBounds)
+            .build();
+    renderer.renderGlop(state, glop);
 }
 
-static void renderVertexBuffer(BakedOpRenderer& renderer, const BakedOpState& state,
-        const VertexBuffer& vertexBuffer, float translateX, float translateY,
-        SkPaint& paint, int vertexBufferRenderFlags) {
-    if (CC_LIKELY(vertexBuffer.getVertexCount())) {
-        bool shadowInterp = vertexBufferRenderFlags & VertexBufferRenderFlags::ShadowInterp;
-        const int transformFlags = TransformFlags::OffsetByFudgeFactor;
-        Glop glop;
-        GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
-                .setRoundRectClipState(state.roundRectClipState)
-                .setMeshVertexBuffer(vertexBuffer, shadowInterp)
-                .setFillPaint(paint, state.alpha)
-                .setTransform(state.computedState.transform, transformFlags)
-                .setModelViewOffsetRect(translateX, translateY, vertexBuffer.getBounds())
-                .build();
-        renderer.renderGlop(state, glop);
+void BakedOpDispatcher::onLinesOp(BakedOpRenderer& renderer, const LinesOp& op, const BakedOpState& state) {
+    VertexBuffer buffer;
+    PathTessellator::tessellateLines(op.points, op.floatCount, op.paint,
+            state.computedState.transform, buffer);
+    int displayFlags = op.paint->isAntiAlias() ? 0 : VertexBufferRenderFlags::Offset;
+    renderVertexBuffer(renderer, state, buffer, 0, 0, *(op.paint), displayFlags);
+}
+
+void BakedOpDispatcher::onOvalOp(BakedOpRenderer& renderer, const OvalOp& op, const BakedOpState& state) {
+    if (op.paint->getPathEffect() != nullptr) {
+        PathTexture* texture = renderer.caches().pathCache.getOval(
+                op.unmappedBounds.getWidth(), op.unmappedBounds.getHeight(), op.paint);
+        const AutoTexture holder(texture);
+        if (CC_LIKELY(holder.texture)) {
+            renderPathTexture(renderer, state, *texture, op);
+        }
+    } else {
+        SkPath path;
+        SkRect rect = getBoundsOfFill(op);
+        path.addOval(rect);
+        renderConvexPath(renderer, state, path, *(op.paint));
+    }
+}
+
+void BakedOpDispatcher::onPatchOp(BakedOpRenderer& renderer, const PatchOp& op, const BakedOpState& state) {
+    // 9 patches are built for stretching - always filter
+    int textureFillFlags = TextureFillFlags::ForceFilter;
+    if (op.bitmap->colorType() == kAlpha_8_SkColorType) {
+        textureFillFlags |= TextureFillFlags::IsAlphaMaskTexture;
+    }
+
+    // TODO: avoid redoing the below work each frame:
+    AssetAtlas::Entry* entry = renderer.renderState().assetAtlas().getEntry(op.bitmap->pixelRef());
+    const Patch* mesh = renderer.caches().patchCache.get(
+            entry, op.bitmap->width(), op.bitmap->height(),
+            op.unmappedBounds.getWidth(), op.unmappedBounds.getHeight(), op.patch);
+
+    Texture* texture = entry ? entry->texture : renderer.caches().textureCache.get(op.bitmap);
+    if (!texture) return;
+    const AutoTexture autoCleanup(texture);
+    Glop glop;
+    GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
+            .setRoundRectClipState(state.roundRectClipState)
+            .setMeshPatchQuads(*mesh)
+            .setMeshTexturedUnitQuad(texture->uvMapper)
+            .setFillTexturePaint(*texture, textureFillFlags, op.paint, state.alpha)
+            .setTransform(state.computedState.transform, TransformFlags::None)
+            .setModelViewOffsetRectSnap(op.unmappedBounds.left, op.unmappedBounds.top,
+                    Rect(op.unmappedBounds.getWidth(), op.unmappedBounds.getHeight()))
+            .build();
+    renderer.renderGlop(state, glop);
+}
+
+void BakedOpDispatcher::onPathOp(BakedOpRenderer& renderer, const PathOp& op, const BakedOpState& state) {
+    PathTexture* texture = renderer.caches().pathCache.get(op.path, op.paint);
+    const AutoTexture holder(texture);
+    if (CC_LIKELY(holder.texture)) {
+        renderPathTexture(renderer, state, *texture, op);
+    }
+}
+
+void BakedOpDispatcher::onPointsOp(BakedOpRenderer& renderer, const PointsOp& op, const BakedOpState& state) {
+    VertexBuffer buffer;
+    PathTessellator::tessellatePoints(op.points, op.floatCount, op.paint,
+            state.computedState.transform, buffer);
+    int displayFlags = op.paint->isAntiAlias() ? 0 : VertexBufferRenderFlags::Offset;
+    renderVertexBuffer(renderer, state, buffer, 0, 0, *(op.paint), displayFlags);
+}
+
+// See SkPaintDefaults.h
+#define SkPaintDefaults_MiterLimit SkIntToScalar(4)
+
+void BakedOpDispatcher::onRectOp(BakedOpRenderer& renderer, const RectOp& op, const BakedOpState& state) {
+    if (op.paint->getStyle() != SkPaint::kFill_Style) {
+        // only fill + default miter is supported by drawConvexPath, since others must handle joins
+        static_assert(SkPaintDefaults_MiterLimit == 4.0f, "Miter limit has changed");
+        if (CC_UNLIKELY(op.paint->getPathEffect() != nullptr
+                || op.paint->getStrokeJoin() != SkPaint::kMiter_Join
+                || op.paint->getStrokeMiter() != SkPaintDefaults_MiterLimit)) {
+             PathTexture* texture = renderer.caches().pathCache.getRect(
+                     op.unmappedBounds.getWidth(), op.unmappedBounds.getHeight(), op.paint);
+             const AutoTexture holder(texture);
+             if (CC_LIKELY(holder.texture)) {
+                 renderPathTexture(renderer, state, *texture, op);
+             }
+        } else {
+            SkPath path;
+            path.addRect(getBoundsOfFill(op));
+            renderConvexPath(renderer, state, path, *(op.paint));
+        }
+    } else {
+        if (op.paint->isAntiAlias() && !state.computedState.transform.isSimple()) {
+            SkPath path;
+            path.addRect(op.unmappedBounds.toSkRect());
+            renderConvexPath(renderer, state, path, *(op.paint));
+        } else {
+            // render simple unit quad, no tessellation required
+            Glop glop;
+            GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
+                    .setRoundRectClipState(state.roundRectClipState)
+                    .setMeshUnitQuad()
+                    .setFillPaint(*op.paint, state.alpha)
+                    .setTransform(state.computedState.transform, TransformFlags::None)
+                    .setModelViewMapUnitToRect(op.unmappedBounds)
+                    .build();
+            renderer.renderGlop(state, glop);
+        }
+    }
+}
+
+void BakedOpDispatcher::onRoundRectOp(BakedOpRenderer& renderer, const RoundRectOp& op, const BakedOpState& state) {
+    if (op.paint->getPathEffect() != nullptr) {
+        PathTexture* texture = renderer.caches().pathCache.getRoundRect(
+                op.unmappedBounds.getWidth(), op.unmappedBounds.getHeight(),
+                op.rx, op.ry, op.paint);
+        const AutoTexture holder(texture);
+        if (CC_LIKELY(holder.texture)) {
+            renderPathTexture(renderer, state, *texture, op);
+        }
+    } else {
+        const VertexBuffer* buffer = renderer.caches().tessellationCache.getRoundRect(
+                state.computedState.transform, *(op.paint),
+                op.unmappedBounds.getWidth(), op.unmappedBounds.getHeight(), op.rx, op.ry);
+        renderVertexBuffer(renderer, state, *buffer,
+                op.unmappedBounds.left, op.unmappedBounds.top, *(op.paint), 0);
     }
 }
 
@@ -153,96 +696,14 @@
     renderer.renderGlop(state, glop);
 }
 
-static void renderTextShadow(BakedOpRenderer& renderer, FontRenderer& fontRenderer,
-        const TextOp& op, const BakedOpState& state) {
-    renderer.caches().textureState().activateTexture(0);
-
-    PaintUtils::TextShadow textShadow;
-    if (!PaintUtils::getTextShadow(op.paint, &textShadow)) {
-        LOG_ALWAYS_FATAL("failed to query shadow attributes");
-    }
-
-    renderer.caches().dropShadowCache.setFontRenderer(fontRenderer);
-    ShadowTexture* texture = renderer.caches().dropShadowCache.get(
-            op.paint, (const char*) op.glyphs,
-            op.glyphCount, textShadow.radius, op.positions);
-    // If the drop shadow exceeds the max texture size or couldn't be
-    // allocated, skip drawing
-    if (!texture) return;
-    const AutoTexture autoCleanup(texture);
-
-    const float sx = op.x - texture->left + textShadow.dx;
-    const float sy = op.y - texture->top + textShadow.dy;
-
-    Glop glop;
-    GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
-            .setRoundRectClipState(state.roundRectClipState)
-            .setMeshTexturedUnitQuad(nullptr)
-            .setFillShadowTexturePaint(*texture, textShadow.color, *op.paint, state.alpha)
-            .setTransform(state.computedState.transform, TransformFlags::None)
-            .setModelViewMapUnitToRect(Rect(sx, sy, sx + texture->width, sy + texture->height))
-            .build();
-    renderer.renderGlop(state, glop);
-}
-
 void BakedOpDispatcher::onTextOp(BakedOpRenderer& renderer, const TextOp& op, const BakedOpState& state) {
-    FontRenderer& fontRenderer = renderer.caches().fontRenderer.getFontRenderer();
-
-    if (CC_UNLIKELY(PaintUtils::hasTextShadow(op.paint))) {
-        fontRenderer.setFont(op.paint, SkMatrix::I());
-        renderTextShadow(renderer, fontRenderer, op, state);
-    }
-
-    float x = op.x;
-    float y = op.y;
-    const Matrix4& transform = state.computedState.transform;
-    const bool pureTranslate = transform.isPureTranslate();
-    if (CC_LIKELY(pureTranslate)) {
-        x = floorf(x + transform.getTranslateX() + 0.5f);
-        y = floorf(y + transform.getTranslateY() + 0.5f);
-        fontRenderer.setFont(op.paint, SkMatrix::I());
-        fontRenderer.setTextureFiltering(false);
-    } else if (CC_UNLIKELY(transform.isPerspective())) {
-        fontRenderer.setFont(op.paint, SkMatrix::I());
-        fontRenderer.setTextureFiltering(true);
-    } else {
-        // We only pass a partial transform to the font renderer. That partial
-        // matrix defines how glyphs are rasterized. Typically we want glyphs
-        // to be rasterized at their final size on screen, which means the partial
-        // matrix needs to take the scale factor into account.
-        // When a partial matrix is used to transform glyphs during rasterization,
-        // the mesh is generated with the inverse transform (in the case of scale,
-        // the mesh is generated at 1.0 / scale for instance.) This allows us to
-        // apply the full transform matrix at draw time in the vertex shader.
-        // Applying the full matrix in the shader is the easiest way to handle
-        // rotation and perspective and allows us to always generated quads in the
-        // font renderer which greatly simplifies the code, clipping in particular.
-        float sx, sy;
-        transform.decomposeScale(sx, sy);
-        fontRenderer.setFont(op.paint, SkMatrix::MakeScale(
-                roundf(std::max(1.0f, sx)),
-                roundf(std::max(1.0f, sy))));
-        fontRenderer.setTextureFiltering(true);
-    }
-
-    // TODO: Implement better clipping for scaled/rotated text
-    const Rect* clip = !pureTranslate ? nullptr : &state.computedState.clipRect;
-    Rect layerBounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
-
-    int alpha = PaintUtils::getAlphaDirect(op.paint) * state.alpha;
-    SkXfermode::Mode mode = PaintUtils::getXfermodeDirect(op.paint);
-    TextDrawFunctor functor(&renderer, &state, x, y, pureTranslate, alpha, mode, op.paint);
-
-    bool hasActiveLayer = false; // TODO
-    fontRenderer.renderPosText(op.paint, clip, (const char*) op.glyphs, op.glyphCount, x, y,
-            op.positions, hasActiveLayer ? &layerBounds : nullptr, &functor, true); // TODO: merging
+    const Rect* clip = state.computedState.clipSideFlags ? &state.computedState.clipRect : nullptr;
+    renderTextOp(renderer, op, state, clip, TextRenderType::Flush);
 }
 
 void BakedOpDispatcher::onLayerOp(BakedOpRenderer& renderer, const LayerOp& op, const BakedOpState& state) {
     OffscreenBuffer* buffer = *op.layerHandle;
 
-    // TODO: extend this to handle HW layers & paint properties which
-    // reside in node.properties().layerProperties()
     float layerAlpha = op.alpha * state.alpha;
     Glop glop;
     GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
diff --git a/libs/hwui/BakedOpDispatcher.h b/libs/hwui/BakedOpDispatcher.h
index caf14bf..ed34ada 100644
--- a/libs/hwui/BakedOpDispatcher.h
+++ b/libs/hwui/BakedOpDispatcher.h
@@ -27,15 +27,24 @@
  * Provides all "onBitmapOp(...)" style static methods for every op type, which convert the
  * RecordedOps and their state to Glops, and renders them with the provided BakedOpRenderer.
  *
- * This dispatcher is separate from the renderer so that the dispatcher / renderer interaction is
- * minimal through public BakedOpRenderer APIs.
+ * onXXXOp methods must either render directly with the renderer, or call a static renderYYY
+ * method to render content. There should never be draw content rejection in BakedOpDispatcher -
+ * it must happen at a higher level (except in error-ish cases, like texture-too-big).
  */
 class BakedOpDispatcher {
 public:
+    // Declares all "onMergedBitmapOps(...)" style methods for mergeable op types
+#define X(Type) \
+        static void onMerged##Type##s(BakedOpRenderer& renderer, const MergedBakedOpList& opList);
+    MAP_MERGED_OPS(X)
+#undef X
+
     // Declares all "onBitmapOp(...)" style methods for every op type
-#define DISPATCH_METHOD(Type) \
+#define X(Type) \
         static void on##Type(BakedOpRenderer& renderer, const Type& op, const BakedOpState& state);
-    MAP_OPS(DISPATCH_METHOD);
+    MAP_OPS(X)
+#undef X
+
 };
 
 }; // namespace uirenderer
diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp
index 6cdc320..93a9406 100644
--- a/libs/hwui/BakedOpRenderer.cpp
+++ b/libs/hwui/BakedOpRenderer.cpp
@@ -121,30 +121,35 @@
 }
 
 Texture* BakedOpRenderer::getTexture(const SkBitmap* bitmap) {
-    Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap);
+    Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap->pixelRef());
     if (!texture) {
         return mCaches.textureCache.get(bitmap);
     }
     return texture;
 }
 
-void BakedOpRenderer::renderGlop(const BakedOpState& state, const Glop& glop) {
-    bool useScissor = state.computedState.clipSideFlags != OpClipSideFlags::None;
-    mRenderState.scissor().setEnabled(useScissor);
-    if (useScissor) {
-        const Rect& clip = state.computedState.clipRect;
-        mRenderState.scissor().set(clip.left, mRenderTarget.viewportHeight - clip.bottom,
-            clip.getWidth(), clip.getHeight());
+void BakedOpRenderer::renderGlop(const Rect* dirtyBounds, const Rect* clip, const Glop& glop) {
+    mRenderState.scissor().setEnabled(clip != nullptr);
+    if (clip) {
+        mRenderState.scissor().set(clip->left, mRenderTarget.viewportHeight - clip->bottom,
+            clip->getWidth(), clip->getHeight());
     }
-    if (mRenderTarget.offscreenBuffer) { // TODO: not with multi-draw
+    if (dirtyBounds && mRenderTarget.offscreenBuffer) {
         // register layer damage to draw-back region
-        const Rect& uiDirty = state.computedState.clippedBounds;
-        android::Rect dirty(uiDirty.left, uiDirty.top, uiDirty.right, uiDirty.bottom);
+        android::Rect dirty(dirtyBounds->left, dirtyBounds->top,
+                dirtyBounds->right, dirtyBounds->bottom);
         mRenderTarget.offscreenBuffer->region.orSelf(dirty);
     }
     mRenderState.render(glop, mRenderTarget.orthoMatrix);
     if (!mRenderTarget.frameBufferId) mHasDrawn = true;
 }
 
+void BakedOpRenderer::dirtyRenderTarget(const Rect& uiDirty) {
+    if (mRenderTarget.offscreenBuffer) {
+        android::Rect dirty(uiDirty.left, uiDirty.top, uiDirty.right, uiDirty.bottom);
+        mRenderTarget.offscreenBuffer->region.orSelf(dirty);
+    }
+}
+
 } // namespace uirenderer
 } // namespace android
diff --git a/libs/hwui/BakedOpRenderer.h b/libs/hwui/BakedOpRenderer.h
index 62d1838..d7600db 100644
--- a/libs/hwui/BakedOpRenderer.h
+++ b/libs/hwui/BakedOpRenderer.h
@@ -67,7 +67,16 @@
     Texture* getTexture(const SkBitmap* bitmap);
     const LightInfo& getLightInfo() { return mLightInfo; }
 
-    void renderGlop(const BakedOpState& state, const Glop& glop);
+    void renderGlop(const BakedOpState& state, const Glop& glop) {
+        bool useScissor = state.computedState.clipSideFlags != OpClipSideFlags::None;
+        renderGlop(&state.computedState.clippedBounds,
+                useScissor ? &state.computedState.clipRect : nullptr,
+                glop);
+    }
+
+    void renderGlop(const Rect* dirtyBounds, const Rect* clip, const Glop& glop);
+    bool offscreenRenderTarget() { return mRenderTarget.offscreenBuffer != nullptr; }
+    void dirtyRenderTarget(const Rect& dirtyRect);
     bool didDraw() { return mHasDrawn; }
 private:
     void setViewport(uint32_t width, uint32_t height);
diff --git a/libs/hwui/BakedOpState.h b/libs/hwui/BakedOpState.h
index 9a40c3b..9c836a0 100644
--- a/libs/hwui/BakedOpState.h
+++ b/libs/hwui/BakedOpState.h
@@ -38,12 +38,22 @@
 }
 
 /**
+ * Holds a list of BakedOpStates of ops that can be drawn together
+ */
+struct MergedBakedOpList {
+    const BakedOpState*const* states;
+    size_t count;
+    int clipSideFlags;
+    Rect clip;
+};
+
+/**
  * Holds the resolved clip, transform, and bounds of a recordedOp, when replayed with a snapshot
  */
 class ResolvedRenderState {
 public:
     // TODO: remove the mapRects/matrix multiply when snapshot & recorded transforms are translates
-    ResolvedRenderState(const Snapshot& snapshot, const RecordedOp& recordedOp) {
+    ResolvedRenderState(const Snapshot& snapshot, const RecordedOp& recordedOp, bool expandForStroke) {
         /* TODO: benchmark a fast path for translate-only matrices, such as:
         if (CC_LIKELY(snapshot.transform->getType() == Matrix4::kTypeTranslate
                 && recordedOp.localMatrix.getType() == Matrix4::kTypeTranslate)) {
@@ -73,7 +83,17 @@
 
         // resolvedClippedBounds = intersect(resolvedMatrix * opBounds, resolvedClipRect)
         clippedBounds = recordedOp.unmappedBounds;
+        if (CC_UNLIKELY(expandForStroke)) {
+            // account for non-hairline stroke
+            clippedBounds.outset(recordedOp.paint->getStrokeWidth() * 0.5f);
+        }
         transform.mapRect(clippedBounds);
+        if (CC_UNLIKELY(expandForStroke
+                && (!transform.isPureTranslate() || recordedOp.paint->getStrokeWidth() < 1.0f))) {
+            // account for hairline stroke when stroke may be < 1 scaled pixel
+            // Non translate || strokeWidth < 1 is conservative, but will cover all cases
+            clippedBounds.outset(0.5f);
+        }
 
         if (clipRect.left > clippedBounds.left) clipSideFlags |= OpClipSideFlags::Left;
         if (clipRect.top > clippedBounds.top) clipSideFlags |= OpClipSideFlags::Top;
@@ -119,13 +139,36 @@
 public:
     static BakedOpState* tryConstruct(LinearAllocator& allocator,
             const Snapshot& snapshot, const RecordedOp& recordedOp) {
-        BakedOpState* bakedOp = new (allocator) BakedOpState(snapshot, recordedOp);
-        if (bakedOp->computedState.clippedBounds.isEmpty()) {
+        BakedOpState* bakedState = new (allocator) BakedOpState(snapshot, recordedOp, false);
+        if (bakedState->computedState.clippedBounds.isEmpty()) {
             // bounds are empty, so op is rejected
-            allocator.rewindIfLastAlloc(bakedOp);
+            allocator.rewindIfLastAlloc(bakedState);
             return nullptr;
         }
-        return bakedOp;
+        return bakedState;
+    }
+
+    enum class StrokeBehavior {
+        // stroking is forced, regardless of style on paint
+        Forced,
+        // stroking is defined by style on paint
+        StyleDefined,
+    };
+
+    static BakedOpState* tryStrokeableOpConstruct(LinearAllocator& allocator,
+            const Snapshot& snapshot, const RecordedOp& recordedOp, StrokeBehavior strokeBehavior) {
+        bool expandForStroke = (strokeBehavior == StrokeBehavior::StyleDefined)
+                ? (recordedOp.paint && recordedOp.paint->getStyle() != SkPaint::kFill_Style)
+                : true;
+
+        BakedOpState* bakedState = new (allocator) BakedOpState(
+                snapshot, recordedOp, expandForStroke);
+        if (bakedState->computedState.clippedBounds.isEmpty()) {
+            // bounds are empty, so op is rejected
+            allocator.rewindIfLastAlloc(bakedState);
+            return nullptr;
+        }
+        return bakedState;
     }
 
     static BakedOpState* tryShadowOpConstruct(LinearAllocator& allocator,
@@ -150,8 +193,8 @@
     const RecordedOp* op;
 
 private:
-    BakedOpState(const Snapshot& snapshot, const RecordedOp& recordedOp)
-            : computedState(snapshot, recordedOp)
+    BakedOpState(const Snapshot& snapshot, const RecordedOp& recordedOp, bool expandForStroke)
+            : computedState(snapshot, recordedOp, expandForStroke)
             , alpha(snapshot.alpha)
             , roundRectClipState(snapshot.roundRectClipState)
             , projectionPathMask(snapshot.projectionPathMask)
diff --git a/libs/hwui/Canvas.h b/libs/hwui/Canvas.h
index b585a27..0643a54 100644
--- a/libs/hwui/Canvas.h
+++ b/libs/hwui/Canvas.h
@@ -113,10 +113,10 @@
 
     // Geometry
     virtual void drawPoint(float x, float y, const SkPaint& paint) = 0;
-    virtual void drawPoints(const float* points, int count, const SkPaint& paint) = 0;
+    virtual void drawPoints(const float* points, int floatCount, const SkPaint& paint) = 0;
     virtual void drawLine(float startX, float startY, float stopX, float stopY,
                 const SkPaint& paint) = 0;
-    virtual void drawLines(const float* points, int count, const SkPaint& paint) = 0;
+    virtual void drawLines(const float* points, int floatCount, const SkPaint& paint) = 0;
     virtual void drawRect(float left, float top, float right, float bottom,
             const SkPaint& paint) = 0;
     virtual void drawRegion(const SkRegion& region, const SkPaint& paint) = 0;
diff --git a/libs/hwui/ClipArea.cpp b/libs/hwui/ClipArea.cpp
index a9d1e42..fd6f0b5 100644
--- a/libs/hwui/ClipArea.cpp
+++ b/libs/hwui/ClipArea.cpp
@@ -26,7 +26,7 @@
 static void handlePoint(Rect& transformedBounds, const Matrix4& transform, float x, float y) {
     Vertex v = {x, y};
     transform.mapPoint(v.x, v.y);
-    transformedBounds.expandToCoverVertex(v.x, v.y);
+    transformedBounds.expandToCover(v.x, v.y);
 }
 
 Rect transformAndCalculateBounds(const Rect& r, const Matrix4& transform) {
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index e7cc464..92217edc 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -612,7 +612,7 @@
     AssetAtlas::Entry* getAtlasEntry(OpenGLRenderer& renderer) {
         if (!mEntryValid) {
             mEntryValid = true;
-            mEntry = renderer.renderState().assetAtlas().getEntry(mBitmap);
+            mEntry = renderer.renderState().assetAtlas().getEntry(mBitmap->pixelRef());
         }
         return mEntry;
     }
@@ -777,7 +777,7 @@
     AssetAtlas::Entry* getAtlasEntry(OpenGLRenderer& renderer) {
         if (!mEntryValid) {
             mEntryValid = true;
-            mEntry = renderer.renderState().assetAtlas().getEntry(mBitmap);
+            mEntry = renderer.renderState().assetAtlas().getEntry(mBitmap->pixelRef());
         }
         return mEntry;
     }
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 47654f4..8acdb62 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -73,9 +73,10 @@
             .setMeshTexturedIndexedQuads(texture.mesh(), texture.meshElementCount())
             .setFillTexturePaint(texture.getTexture(), textureFillFlags, paint, bakedState->alpha)
             .setTransform(bakedState->computedState.transform, transformFlags)
-            .setModelViewOffsetRect(0, 0, Rect(0, 0, 0, 0))
+            .setModelViewIdentityEmptyBounds()
             .build();
-    renderer->renderGlop(*bakedState, glop);
+    // Note: don't pass dirty bounds here, so user must manage passing dirty bounds to renderer
+    renderer->renderGlop(nullptr, clip, glop);
 #else
     GlopBuilder(renderer->mRenderState, renderer->mCaches, &glop)
             .setRoundRectClipState(renderer->currentSnapshot()->roundRectClipState)
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index 87cfe7f..ff4dc4a 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -57,6 +57,7 @@
 #if HWUI_NEW_OPS
             BakedOpRenderer* renderer,
             const BakedOpState* bakedState,
+            const Rect* clip,
 #else
             OpenGLRenderer* renderer,
 #endif
@@ -65,6 +66,7 @@
         : renderer(renderer)
 #if HWUI_NEW_OPS
         , bakedState(bakedState)
+        , clip(clip)
 #endif
         , x(x)
         , y(y)
@@ -79,6 +81,7 @@
 #if HWUI_NEW_OPS
     BakedOpRenderer* renderer;
     const BakedOpState* bakedState;
+    const Rect* clip;
 #else
     OpenGLRenderer* renderer;
 #endif
diff --git a/libs/hwui/Glop.h b/libs/hwui/Glop.h
index 4785ea4..bcf819e 100644
--- a/libs/hwui/Glop.h
+++ b/libs/hwui/Glop.h
@@ -64,7 +64,7 @@
 
         // Canvas transform isn't applied to the mesh at draw time,
         //since it's already built in.
-        MeshIgnoresCanvasTransform = 1 << 1,
+        MeshIgnoresCanvasTransform = 1 << 1, // TODO: remove
     };
 };
 
diff --git a/libs/hwui/GlopBuilder.h b/libs/hwui/GlopBuilder.h
index 6270dcb..6e5797d 100644
--- a/libs/hwui/GlopBuilder.h
+++ b/libs/hwui/GlopBuilder.h
@@ -53,7 +53,7 @@
     GlopBuilder& setMeshTexturedUvQuad(const UvMapper* uvMapper, const Rect uvs);
     GlopBuilder& setMeshVertexBuffer(const VertexBuffer& vertexBuffer, bool shadowInterp);
     GlopBuilder& setMeshIndexedQuads(Vertex* vertexData, int quadCount);
-    GlopBuilder& setMeshTexturedMesh(TextureVertex* vertexData, int elementCount); // TODO: use indexed quads
+    GlopBuilder& setMeshTexturedMesh(TextureVertex* vertexData, int elementCount); // TODO: delete
     GlopBuilder& setMeshColoredTexturedMesh(ColorTextureVertex* vertexData, int elementCount); // TODO: use indexed quads
     GlopBuilder& setMeshTexturedIndexedQuads(TextureVertex* vertexData, int elementCount); // TODO: take quadCount
     GlopBuilder& setMeshPatchQuads(const Patch& patch);
@@ -95,6 +95,10 @@
             return setModelViewOffsetRect(offsetX, offsetY, source);
         }
     }
+    GlopBuilder& setModelViewIdentityEmptyBounds() {
+        // pass empty rect since not needed for damage / snap
+        return setModelViewOffsetRect(0, 0, Rect());
+    }
 
     GlopBuilder& setRoundRectClipState(const RoundRectClipState* roundRectClipState);
 
diff --git a/libs/hwui/OpReorderer.cpp b/libs/hwui/OpReorderer.cpp
index 9cbd9c2d..ec03e83 100644
--- a/libs/hwui/OpReorderer.cpp
+++ b/libs/hwui/OpReorderer.cpp
@@ -202,6 +202,9 @@
         if (newClipSideFlags & OpClipSideFlags::Bottom) mClipRect.bottom = opClip.bottom;
     }
 
+    bool getClipSideFlags() const { return mClipSideFlags; }
+    const Rect& getClipRect() const { return mClipRect; }
+
 private:
     int mClipSideFlags = 0;
     Rect mClipRect;
@@ -291,12 +294,31 @@
     }
 }
 
-void OpReorderer::LayerReorderer::replayBakedOpsImpl(void* arg, BakedOpDispatcher* receivers) const {
+void OpReorderer::LayerReorderer::replayBakedOpsImpl(void* arg,
+        BakedOpReceiver* unmergedReceivers, MergedOpReceiver* mergedReceivers) const {
     ATRACE_NAME("flush drawing commands");
     for (const BatchBase* batch : mBatches) {
-        // TODO: different behavior based on batch->isMerging()
-        for (const BakedOpState* op : batch->getOps()) {
-            receivers[op->op->opId](arg, *op->op, *op);
+        size_t size = batch->getOps().size();
+        if (size > 1 && batch->isMerging()) {
+            int opId = batch->getOps()[0]->op->opId;
+            const MergingOpBatch* mergingBatch = static_cast<const MergingOpBatch*>(batch);
+            MergedBakedOpList data = {
+                    batch->getOps().data(),
+                    size,
+                    mergingBatch->getClipSideFlags(),
+                    mergingBatch->getClipRect()
+            };
+            if (data.clipSideFlags) {
+                // if right or bottom sides aren't used to clip, init them to viewport bounds
+                // in the clip rect, so it can be used to scissor
+                if (!(data.clipSideFlags & OpClipSideFlags::Right)) data.clip.right = width;
+                if (!(data.clipSideFlags & OpClipSideFlags::Bottom)) data.clip.bottom = height;
+            }
+            mergedReceivers[opId](arg, data);
+        } else {
+            for (const BakedOpState* op : batch->getOps()) {
+                unmergedReceivers[op->op->opId](arg, *op);
+            }
         }
     }
 }
@@ -445,13 +467,13 @@
             // (temp layers are clipped to viewport, since they don't persist offscreen content)
             SkPaint saveLayerPaint;
             saveLayerPaint.setAlpha(properties.getAlpha());
-            onBeginLayerOp(*new (mAllocator) BeginLayerOp(
+            deferBeginLayerOp(*new (mAllocator) BeginLayerOp(
                     saveLayerBounds,
                     Matrix4::identity(),
                     saveLayerBounds,
                     &saveLayerPaint));
             deferNodeOps(node);
-            onEndLayerOp(*new (mAllocator) EndLayerOp());
+            deferEndLayerOp(*new (mAllocator) EndLayerOp());
         } else {
             deferNodeOps(node);
         }
@@ -537,7 +559,7 @@
         }
 
         const RenderNodeOp* childOp = zTranslatedNodes[drawIndex].value;
-        deferRenderNodeOp(*childOp);
+        deferRenderNodeOpImpl(*childOp);
         drawIndex++;
     }
 }
@@ -623,7 +645,7 @@
 
         int restoreTo = mCanvasState.save(SkCanvas::kMatrix_SaveFlag);
         mCanvasState.concatMatrix(childOp->transformFromCompositingAncestor);
-        deferRenderNodeOp(*childOp);
+        deferRenderNodeOpImpl(*childOp);
         mCanvasState.restoreToCount(restoreTo);
     }
 
@@ -631,15 +653,16 @@
 }
 
 /**
- * Used to define a list of lambdas referencing private OpReorderer::onXXXXOp() methods.
+ * Used to define a list of lambdas referencing private OpReorderer::onXX::defer() methods.
  *
  * This allows opIds embedded in the RecordedOps to be used for dispatching to these lambdas.
  * E.g. a BitmapOp op then would be dispatched to OpReorderer::onBitmapOp(const BitmapOp&)
  */
 #define OP_RECEIVER(Type) \
-        [](OpReorderer& reorderer, const RecordedOp& op) { reorderer.on##Type(static_cast<const Type&>(op)); },
+        [](OpReorderer& reorderer, const RecordedOp& op) { reorderer.defer##Type(static_cast<const Type&>(op)); },
 void OpReorderer::deferNodeOps(const RenderNode& renderNode) {
-    static std::function<void(OpReorderer& reorderer, const RecordedOp&)> receivers[] = {
+    typedef void (*OpDispatcher) (OpReorderer& reorderer, const RecordedOp& op);
+    static OpDispatcher receivers[] = {
         MAP_OPS(OP_RECEIVER)
     };
 
@@ -664,7 +687,7 @@
     }
 }
 
-void OpReorderer::deferRenderNodeOp(const RenderNodeOp& op) {
+void OpReorderer::deferRenderNodeOpImpl(const RenderNodeOp& op) {
     if (op.renderNode->nothingToDraw()) return;
     int count = mCanvasState.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag);
 
@@ -679,55 +702,163 @@
     mCanvasState.restoreToCount(count);
 }
 
-void OpReorderer::onRenderNodeOp(const RenderNodeOp& op) {
+void OpReorderer::deferRenderNodeOp(const RenderNodeOp& op) {
     if (!op.skipInOrderDraw) {
-        deferRenderNodeOp(op);
+        deferRenderNodeOpImpl(op);
     }
 }
 
-static batchid_t tessellatedBatchId(const SkPaint& paint) {
+/**
+ * Defers an unmergeable, strokeable op, accounting correctly
+ * for paint's style on the bounds being computed.
+ */
+void OpReorderer::deferStrokeableOp(const RecordedOp& op, batchid_t batchId,
+        BakedOpState::StrokeBehavior strokeBehavior) {
+    // Note: here we account for stroke when baking the op
+    BakedOpState* bakedState = BakedOpState::tryStrokeableOpConstruct(
+            mAllocator, *mCanvasState.currentSnapshot(), op, strokeBehavior);
+    if (!bakedState) return; // quick rejected
+    currentLayer().deferUnmergeableOp(mAllocator, bakedState, batchId);
+}
+
+/**
+ * Returns batch id for tessellatable shapes, based on paint. Checks to see if path effect/AA will
+ * be used, since they trigger significantly different rendering paths.
+ *
+ * Note: not used for lines/points, since they don't currently support path effects.
+ */
+static batchid_t tessBatchId(const RecordedOp& op) {
+    const SkPaint& paint = *(op.paint);
     return paint.getPathEffect()
             ? OpBatchType::AlphaMaskTexture
             : (paint.isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices);
 }
 
-void OpReorderer::onBitmapOp(const BitmapOp& op) {
-    BakedOpState* bakedStateOp = tryBakeOpState(op);
-    if (!bakedStateOp) return; // quick rejected
-
-    mergeid_t mergeId = (mergeid_t) op.bitmap->getGenerationID();
-    // TODO: AssetAtlas
-    currentLayer().deferMergeableOp(mAllocator, bakedStateOp, OpBatchType::Bitmap, mergeId);
+void OpReorderer::deferArcOp(const ArcOp& op) {
+    deferStrokeableOp(op, tessBatchId(op));
 }
 
-void OpReorderer::onLinesOp(const LinesOp& op) {
-    BakedOpState* bakedStateOp = tryBakeOpState(op);
-    if (!bakedStateOp) return; // quick rejected
-    currentLayer().deferUnmergeableOp(mAllocator, bakedStateOp, OpBatchType::Vertices);
+void OpReorderer::deferBitmapOp(const BitmapOp& op) {
+    BakedOpState* bakedState = tryBakeOpState(op);
+    if (!bakedState) return; // quick rejected
 
+    // Don't merge non-simply transformed or neg scale ops, SET_TEXTURE doesn't handle rotation
+    // Don't merge A8 bitmaps - the paint's color isn't compared by mergeId, or in
+    // MergingDrawBatch::canMergeWith()
+    if (bakedState->computedState.transform.isSimple()
+            && bakedState->computedState.transform.positiveScale()
+            && PaintUtils::getXfermodeDirect(op.paint) == SkXfermode::kSrcOver_Mode
+            && op.bitmap->colorType() != kAlpha_8_SkColorType) {
+        mergeid_t mergeId = (mergeid_t) op.bitmap->getGenerationID();
+        // TODO: AssetAtlas in mergeId
+        currentLayer().deferMergeableOp(mAllocator, bakedState, OpBatchType::Bitmap, mergeId);
+    } else {
+        currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap);
+    }
 }
 
-void OpReorderer::onRectOp(const RectOp& op) {
-    BakedOpState* bakedStateOp = tryBakeOpState(op);
-    if (!bakedStateOp) return; // quick rejected
-    currentLayer().deferUnmergeableOp(mAllocator, bakedStateOp, tessellatedBatchId(*op.paint));
+void OpReorderer::deferBitmapMeshOp(const BitmapMeshOp& op) {
+    BakedOpState* bakedState = tryBakeOpState(op);
+    if (!bakedState) return; // quick rejected
+    currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap);
 }
 
-void OpReorderer::onSimpleRectsOp(const SimpleRectsOp& op) {
-    BakedOpState* bakedStateOp = tryBakeOpState(op);
-    if (!bakedStateOp) return; // quick rejected
-    currentLayer().deferUnmergeableOp(mAllocator, bakedStateOp, OpBatchType::Vertices);
+void OpReorderer::deferBitmapRectOp(const BitmapRectOp& op) {
+    BakedOpState* bakedState = tryBakeOpState(op);
+    if (!bakedState) return; // quick rejected
+    currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap);
 }
 
-void OpReorderer::onTextOp(const TextOp& op) {
-    BakedOpState* bakedStateOp = tryBakeOpState(op);
-    if (!bakedStateOp) return; // quick rejected
+void OpReorderer::deferCirclePropsOp(const CirclePropsOp& op) {
+    // allocate a temporary oval op (with mAllocator, so it persists until render), so the
+    // renderer doesn't have to handle the RoundRectPropsOp type, and so state baking is simple.
+    float x = *(op.x);
+    float y = *(op.y);
+    float radius = *(op.radius);
+    Rect unmappedBounds(x - radius, y - radius, x + radius, y + radius);
+    const OvalOp* resolvedOp = new (mAllocator) OvalOp(
+            unmappedBounds,
+            op.localMatrix,
+            op.localClipRect,
+            op.paint);
+    deferOvalOp(*resolvedOp);
+}
+
+void OpReorderer::deferLinesOp(const LinesOp& op) {
+    batchid_t batch = op.paint->isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices;
+    deferStrokeableOp(op, batch, BakedOpState::StrokeBehavior::Forced);
+}
+
+void OpReorderer::deferOvalOp(const OvalOp& op) {
+    deferStrokeableOp(op, tessBatchId(op));
+}
+
+void OpReorderer::deferPatchOp(const PatchOp& op) {
+    BakedOpState* bakedState = tryBakeOpState(op);
+    if (!bakedState) return; // quick rejected
+
+    if (bakedState->computedState.transform.isPureTranslate()
+            && PaintUtils::getXfermodeDirect(op.paint) == SkXfermode::kSrcOver_Mode) {
+        mergeid_t mergeId = (mergeid_t) op.bitmap->getGenerationID();
+        // TODO: AssetAtlas in mergeId
+
+        // Only use the MergedPatch batchId when merged, so Bitmap+Patch don't try to merge together
+        currentLayer().deferMergeableOp(mAllocator, bakedState, OpBatchType::MergedPatch, mergeId);
+    } else {
+        // Use Bitmap batchId since Bitmap+Patch use same shader
+        currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap);
+    }
+}
+
+void OpReorderer::deferPathOp(const PathOp& op) {
+    deferStrokeableOp(op, OpBatchType::Bitmap);
+}
+
+void OpReorderer::deferPointsOp(const PointsOp& op) {
+    batchid_t batch = op.paint->isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices;
+    deferStrokeableOp(op, batch, BakedOpState::StrokeBehavior::Forced);
+}
+
+void OpReorderer::deferRectOp(const RectOp& op) {
+    deferStrokeableOp(op, tessBatchId(op));
+}
+
+void OpReorderer::deferRoundRectOp(const RoundRectOp& op) {
+    deferStrokeableOp(op, tessBatchId(op));
+}
+
+void OpReorderer::deferRoundRectPropsOp(const RoundRectPropsOp& op) {
+    // allocate a temporary round rect op (with mAllocator, so it persists until render), so the
+    // renderer doesn't have to handle the RoundRectPropsOp type, and so state baking is simple.
+    const RoundRectOp* resolvedOp = new (mAllocator) RoundRectOp(
+            Rect(*(op.left), *(op.top), *(op.right), *(op.bottom)),
+            op.localMatrix,
+            op.localClipRect,
+            op.paint, *op.rx, *op.ry);
+    deferRoundRectOp(*resolvedOp);
+}
+
+void OpReorderer::deferSimpleRectsOp(const SimpleRectsOp& op) {
+    BakedOpState* bakedState = tryBakeOpState(op);
+    if (!bakedState) return; // quick rejected
+    currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Vertices);
+}
+
+void OpReorderer::deferTextOp(const TextOp& op) {
+    BakedOpState* bakedState = tryBakeOpState(op);
+    if (!bakedState) return; // quick rejected
 
     // TODO: better handling of shader (since we won't care about color then)
     batchid_t batchId = op.paint->getColor() == SK_ColorBLACK
             ? OpBatchType::Text : OpBatchType::ColorText;
-    mergeid_t mergeId = reinterpret_cast<mergeid_t>(op.paint->getColor());
-    currentLayer().deferMergeableOp(mAllocator, bakedStateOp, batchId, mergeId);
+
+    if (bakedState->computedState.transform.isPureTranslate()
+            && PaintUtils::getXfermodeDirect(op.paint) == SkXfermode::kSrcOver_Mode) {
+        mergeid_t mergeId = reinterpret_cast<mergeid_t>(op.paint->getColor());
+        currentLayer().deferMergeableOp(mAllocator, bakedState, batchId, mergeId);
+    } else {
+        currentLayer().deferUnmergeableOp(mAllocator, bakedState, batchId);
+    }
 }
 
 void OpReorderer::saveForLayer(uint32_t layerWidth, uint32_t layerHeight,
@@ -756,7 +887,7 @@
 }
 
 // TODO: test rejection at defer time, where the bounds become empty
-void OpReorderer::onBeginLayerOp(const BeginLayerOp& op) {
+void OpReorderer::deferBeginLayerOp(const BeginLayerOp& op) {
     uint32_t layerWidth = (uint32_t) op.unmappedBounds.getWidth();
     uint32_t layerHeight = (uint32_t) op.unmappedBounds.getHeight();
 
@@ -801,7 +932,7 @@
             &op, nullptr);
 }
 
-void OpReorderer::onEndLayerOp(const EndLayerOp& /* ignored */) {
+void OpReorderer::deferEndLayerOp(const EndLayerOp& /* ignored */) {
     const BeginLayerOp& beginLayerOp = *currentLayer().beginLayerOp;
     int finishedLayerIndex = mLayerStack.back();
 
@@ -827,11 +958,11 @@
     }
 }
 
-void OpReorderer::onLayerOp(const LayerOp& op) {
+void OpReorderer::deferLayerOp(const LayerOp& op) {
     LOG_ALWAYS_FATAL("unsupported");
 }
 
-void OpReorderer::onShadowOp(const ShadowOp& op) {
+void OpReorderer::deferShadowOp(const ShadowOp& op) {
     LOG_ALWAYS_FATAL("unsupported");
 }
 
diff --git a/libs/hwui/OpReorderer.h b/libs/hwui/OpReorderer.h
index 00df8b0..35343c8b 100644
--- a/libs/hwui/OpReorderer.h
+++ b/libs/hwui/OpReorderer.h
@@ -45,7 +45,7 @@
     enum {
         None = 0, // Don't batch
         Bitmap,
-        Patch,
+        MergedPatch,
         AlphaVertices,
         Vertices,
         AlphaMaskTexture,
@@ -58,7 +58,8 @@
 }
 
 class OpReorderer : public CanvasStateClient {
-    typedef std::function<void(void*, const RecordedOp&, const BakedOpState&)> BakedOpDispatcher;
+    typedef void (*BakedOpReceiver)(void*, const BakedOpState&);
+    typedef void (*MergedOpReceiver)(void*, const MergedBakedOpList& opList);
 
     /**
      * Stores the deferred render operations and state used to compute ordering
@@ -87,7 +88,7 @@
         void deferMergeableOp(LinearAllocator& allocator,
                 BakedOpState* op, batchid_t batchId, mergeid_t mergeId);
 
-        void replayBakedOpsImpl(void* arg, BakedOpDispatcher* receivers) const;
+        void replayBakedOpsImpl(void* arg, BakedOpReceiver* receivers, MergedOpReceiver*) const;
 
         bool empty() const {
             return mBatches.empty();
@@ -132,19 +133,44 @@
      * It constructs a lookup array of lambdas, which allows a recorded BakeOpState to use
      * state->op->opId to lookup a receiver that will be called when the op is replayed.
      *
-     * For example a BitmapOp would resolve, via the lambda lookup, to calling:
-     *
-     * StaticDispatcher::onBitmapOp(Renderer& renderer, const BitmapOp& op, const BakedOpState& state);
      */
-#define BAKED_OP_RECEIVER(Type) \
-    [](void* internalRenderer, const RecordedOp& op, const BakedOpState& state) { \
-        StaticDispatcher::on##Type(*(static_cast<Renderer*>(internalRenderer)), static_cast<const Type&>(op), state); \
-    },
     template <typename StaticDispatcher, typename Renderer>
     void replayBakedOps(Renderer& renderer) {
-        static BakedOpDispatcher receivers[] = {
-            MAP_OPS(BAKED_OP_RECEIVER)
+        /**
+         * defines a LUT of lambdas which allow a recorded BakedOpState to use state->op->opId to
+         * dispatch the op via a method on a static dispatcher when the op is replayed.
+         *
+         * For example a BitmapOp would resolve, via the lambda lookup, to calling:
+         *
+         * StaticDispatcher::onBitmapOp(Renderer& renderer, const BitmapOp& op, const BakedOpState& state);
+         */
+        #define X(Type) \
+                [](void* renderer, const BakedOpState& state) { \
+                    StaticDispatcher::on##Type(*(static_cast<Renderer*>(renderer)), static_cast<const Type&>(*(state.op)), state); \
+                },
+        static BakedOpReceiver unmergedReceivers[] = {
+            MAP_OPS(X)
         };
+        #undef X
+
+        /**
+         * defines a LUT of lambdas which allow merged arrays of BakedOpState* to be passed to a
+         * static dispatcher when the group of merged ops is replayed. Unmergeable ops trigger
+         * a LOG_ALWAYS_FATAL().
+         */
+        #define X(Type) \
+                [](void* renderer, const MergedBakedOpList& opList) { \
+                    LOG_ALWAYS_FATAL("op type %d does not support merging", opList.states[0]->op->opId); \
+                },
+        #define Y(Type) \
+                [](void* renderer, const MergedBakedOpList& opList) { \
+                    StaticDispatcher::onMerged##Type##s(*(static_cast<Renderer*>(renderer)), opList); \
+                },
+        static MergedOpReceiver mergedReceivers[] = {
+            MAP_OPS_BASED_ON_MERGEABILITY(X, Y)
+        };
+        #undef X
+        #undef Y
 
         // Relay through layers in reverse order, since layers
         // later in the list will be drawn by earlier ones
@@ -153,18 +179,18 @@
             if (layer.renderNode) {
                 // cached HW layer - can't skip layer if empty
                 renderer.startRepaintLayer(layer.offscreenBuffer, layer.repaintRect);
-                layer.replayBakedOpsImpl((void*)&renderer, receivers);
+                layer.replayBakedOpsImpl((void*)&renderer, unmergedReceivers, mergedReceivers);
                 renderer.endLayer();
             } else if (!layer.empty()) { // save layer - skip entire layer if empty
                 layer.offscreenBuffer = renderer.startTemporaryLayer(layer.width, layer.height);
-                layer.replayBakedOpsImpl((void*)&renderer, receivers);
+                layer.replayBakedOpsImpl((void*)&renderer, unmergedReceivers, mergedReceivers);
                 renderer.endLayer();
             }
         }
 
         const LayerReorderer& fbo0 = mLayerReorderers[0];
         renderer.startFrame(fbo0.width, fbo0.height, fbo0.repaintRect);
-        fbo0.replayBakedOpsImpl((void*)&renderer, receivers);
+        fbo0.replayBakedOpsImpl((void*)&renderer, unmergedReceivers, mergedReceivers);
         renderer.endFrame();
     }
 
@@ -211,22 +237,26 @@
 
     void deferNodeOps(const RenderNode& renderNode);
 
-    void deferRenderNodeOp(const RenderNodeOp& op);
+    void deferRenderNodeOpImpl(const RenderNodeOp& op);
 
-    void replayBakedOpsImpl(void* arg, BakedOpDispatcher* receivers);
+    void replayBakedOpsImpl(void* arg, BakedOpReceiver* receivers);
 
     SkPath* createFrameAllocatedPath() {
         mFrameAllocatedPaths.emplace_back(new SkPath);
         return mFrameAllocatedPaths.back().get();
     }
+
+    void deferStrokeableOp(const RecordedOp& op, batchid_t batchId,
+            BakedOpState::StrokeBehavior strokeBehavior = BakedOpState::StrokeBehavior::StyleDefined);
+
     /**
-     * Declares all OpReorderer::onXXXXOp() methods for every RecordedOp type.
+     * Declares all OpReorderer::deferXXXXOp() methods for every RecordedOp type.
      *
      * These private methods are called from within deferImpl to defer each individual op
      * type differently.
      */
 #define INTERNAL_OP_HANDLER(Type) \
-    void on##Type(const Type& op);
+    void defer##Type(const Type& op);
     MAP_OPS(INTERNAL_OP_HANDLER)
 
     std::vector<std::unique_ptr<SkPath> > mFrameAllocatedPaths;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index e386b1c..f49237c 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -40,6 +40,7 @@
 
 #include <SkCanvas.h>
 #include <SkColor.h>
+#include <SkPaintDefaults.h>
 #include <SkPathOps.h>
 #include <SkShader.h>
 #include <SkTypeface.h>
@@ -1525,7 +1526,7 @@
         colors = tempColors.get();
     }
 
-    Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap);
+    Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap->pixelRef());
     const UvMapper& mapper(getMapper(texture));
 
     for (int32_t y = 0; y < meshHeight; y++) {
@@ -1908,9 +1909,6 @@
     drawConvexPath(path, p);
 }
 
-// See SkPaintDefaults.h
-#define SkPaintDefaults_MiterLimit SkIntToScalar(4)
-
 void OpenGLRenderer::drawRect(float left, float top, float right, float bottom,
         const SkPaint* p) {
     if (mState.currentlyIgnored()
@@ -1921,6 +1919,7 @@
 
     if (p->getStyle() != SkPaint::kFill_Style) {
         // only fill style is supported by drawConvexPath, since others have to handle joins
+        static_assert(SkPaintDefaults_MiterLimit == 4.0f, "Miter limit has changed");
         if (p->getPathEffect() != nullptr || p->getStrokeJoin() != SkPaint::kMiter_Join ||
                 p->getStrokeMiter() != SkPaintDefaults_MiterLimit) {
             mCaches.textureState().activateTexture(0);
@@ -2146,7 +2145,7 @@
     bool status;
 #if HWUI_NEW_OPS
     LOG_ALWAYS_FATAL("unsupported");
-    TextDrawFunctor functor(nullptr, nullptr, x, y, pureTranslate, alpha, mode, paint);
+    TextDrawFunctor functor(nullptr, nullptr, nullptr, x, y, pureTranslate, alpha, mode, paint);
 #else
     TextDrawFunctor functor(this, x, y, pureTranslate, alpha, mode, paint);
 #endif
@@ -2190,7 +2189,7 @@
     SkXfermode::Mode mode = PaintUtils::getXfermodeDirect(paint);
 #if HWUI_NEW_OPS
     LOG_ALWAYS_FATAL("unsupported");
-    TextDrawFunctor functor(nullptr, nullptr, 0.0f, 0.0f, false, alpha, mode, paint);
+    TextDrawFunctor functor(nullptr, nullptr, nullptr, 0.0f, 0.0f, false, alpha, mode, paint);
 #else
     TextDrawFunctor functor(this, 0.0f, 0.0f, false, alpha, mode, paint);
 #endif
@@ -2308,7 +2307,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 Texture* OpenGLRenderer::getTexture(const SkBitmap* bitmap) {
-    Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap);
+    Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap->pixelRef());
     if (!texture) {
         return mCaches.textureCache.get(bitmap);
     }
diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp
index b57b8f0..9246237 100644
--- a/libs/hwui/PathTessellator.cpp
+++ b/libs/hwui/PathTessellator.cpp
@@ -799,7 +799,7 @@
     dstBuffer.alloc<TYPE>(numPoints * verticesPerPoint + (numPoints - 1) * 2);
 
     for (int i = 0; i < count; i += 2) {
-        bounds.expandToCoverVertex(points[i + 0], points[i + 1]);
+        bounds.expandToCover(points[i + 0], points[i + 1]);
         dstBuffer.copyInto<TYPE>(srcBuffer, points[i + 0], points[i + 1]);
     }
     dstBuffer.createDegenerateSeparators<TYPE>(verticesPerPoint);
@@ -878,8 +878,8 @@
         }
 
         // calculate bounds
-        bounds.expandToCoverVertex(tempVerticesData[0].x, tempVerticesData[0].y);
-        bounds.expandToCoverVertex(tempVerticesData[1].x, tempVerticesData[1].y);
+        bounds.expandToCover(tempVerticesData[0].x, tempVerticesData[0].y);
+        bounds.expandToCover(tempVerticesData[1].x, tempVerticesData[1].y);
     }
 
     // since multiple objects tessellated into buffer, separate them with degen tris
diff --git a/libs/hwui/RecordedOp.h b/libs/hwui/RecordedOp.h
index b4a201e..d1a4866 100644
--- a/libs/hwui/RecordedOp.h
+++ b/libs/hwui/RecordedOp.h
@@ -24,7 +24,8 @@
 #include "utils/LinearAllocator.h"
 #include "Vector.h"
 
-#include "SkXfermode.h"
+#include <androidfw/ResourceTypes.h>
+#include <SkXfermode.h>
 
 class SkBitmap;
 class SkPaint;
@@ -37,21 +38,44 @@
 struct Vertex;
 
 /**
- * The provided macro is executed for each op type in order, with the results separated by commas.
+ * On of the provided macros is executed for each op type in order. The first will be used for ops
+ * that cannot merge, and the second for those that can.
  *
  * This serves as the authoritative list of ops, used for generating ID enum, and ID based LUTs.
  */
+#define MAP_OPS_BASED_ON_MERGEABILITY(U_OP_FN, M_OP_FN) \
+        U_OP_FN(ArcOp) \
+        M_OP_FN(BitmapOp) \
+        U_OP_FN(BitmapMeshOp) \
+        U_OP_FN(BitmapRectOp) \
+        U_OP_FN(CirclePropsOp) \
+        U_OP_FN(LinesOp) \
+        U_OP_FN(OvalOp) \
+        M_OP_FN(PatchOp) \
+        U_OP_FN(PathOp) \
+        U_OP_FN(PointsOp) \
+        U_OP_FN(RectOp) \
+        U_OP_FN(RenderNodeOp) \
+        U_OP_FN(RoundRectOp) \
+        U_OP_FN(RoundRectPropsOp) \
+        U_OP_FN(ShadowOp) \
+        U_OP_FN(SimpleRectsOp) \
+        M_OP_FN(TextOp) \
+        U_OP_FN(BeginLayerOp) \
+        U_OP_FN(EndLayerOp) \
+        U_OP_FN(LayerOp)
+
+/**
+ * The provided macro is executed for each op type in order. This is used in cases where
+ * merge-ability of ops doesn't matter.
+ */
 #define MAP_OPS(OP_FN) \
-        OP_FN(BitmapOp) \
-        OP_FN(LinesOp) \
-        OP_FN(RectOp) \
-        OP_FN(RenderNodeOp) \
-        OP_FN(ShadowOp) \
-        OP_FN(SimpleRectsOp) \
-        OP_FN(TextOp) \
-        OP_FN(BeginLayerOp) \
-        OP_FN(EndLayerOp) \
-        OP_FN(LayerOp)
+        MAP_OPS_BASED_ON_MERGEABILITY(OP_FN, OP_FN)
+
+#define NULL_OP_FN(Type)
+
+#define MAP_MERGED_OPS(OP_FN) \
+        MAP_OPS_BASED_ON_MERGEABILITY(NULL_OP_FN, OP_FN)
 
 // Generate OpId enum
 #define IDENTITY_FN(Type) Type,
@@ -61,7 +85,7 @@
         Count,
     };
 }
-static_assert(RecordedOpId::BitmapOp == 0,
+static_assert(RecordedOpId::ArcOp == 0,
         "First index must be zero for LUTs to work");
 
 #define BASE_PARAMS const Rect& unmappedBounds, const Matrix4& localMatrix, const Rect& localClipRect, const SkPaint* paint
@@ -73,7 +97,7 @@
     /* ID from RecordedOpId - generally used for jumping into function tables */
     const int opId;
 
-    /* bounds in *local* space, without accounting for DisplayList transformation */
+    /* bounds in *local* space, without accounting for DisplayList transformation, or stroke */
     const Rect unmappedBounds;
 
     /* transform in recording space (vs DisplayList origin) */
@@ -115,6 +139,17 @@
 // Standard Ops
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
+struct ArcOp : RecordedOp {
+    ArcOp(BASE_PARAMS, float startAngle, float sweepAngle, bool useCenter)
+            : SUPER(ArcOp)
+            , startAngle(startAngle)
+            , sweepAngle(sweepAngle)
+            , useCenter(useCenter) {}
+    const float startAngle;
+    const float sweepAngle;
+    const bool useCenter;
+};
+
 struct BitmapOp : RecordedOp {
     BitmapOp(BASE_PARAMS, const SkBitmap* bitmap)
             : SUPER(BitmapOp)
@@ -123,6 +158,43 @@
     // TODO: asset atlas/texture id lookup?
 };
 
+struct BitmapMeshOp : RecordedOp {
+    BitmapMeshOp(BASE_PARAMS, const SkBitmap* bitmap, int meshWidth, int meshHeight,
+            const float* vertices, const int* colors)
+            : SUPER(BitmapMeshOp)
+            , bitmap(bitmap)
+            , meshWidth(meshWidth)
+            , meshHeight(meshHeight)
+            , vertices(vertices)
+            , colors(colors) {}
+    const SkBitmap* bitmap;
+    const int meshWidth;
+    const int meshHeight;
+    const float* vertices;
+    const int* colors;
+};
+
+struct BitmapRectOp : RecordedOp {
+    BitmapRectOp(BASE_PARAMS, const SkBitmap* bitmap, const Rect& src)
+            : SUPER(BitmapRectOp)
+            , bitmap(bitmap)
+            , src(src) {}
+    const SkBitmap* bitmap;
+    const Rect src;
+};
+
+struct CirclePropsOp : RecordedOp {
+    CirclePropsOp(const Matrix4& localMatrix, const Rect& localClipRect, const SkPaint* paint,
+            float* x, float* y, float* radius)
+            : RecordedOp(RecordedOpId::CirclePropsOp, Rect(), localMatrix, localClipRect, paint)
+            , x(x)
+            , y(y)
+            , radius(radius) {}
+    const float* x;
+    const float* y;
+    const float* radius;
+};
+
 struct LinesOp : RecordedOp {
     LinesOp(BASE_PARAMS, const float* points, const int floatCount)
             : SUPER(LinesOp)
@@ -132,11 +204,68 @@
     const int floatCount;
 };
 
+struct OvalOp : RecordedOp {
+    OvalOp(BASE_PARAMS)
+            : SUPER(OvalOp) {}
+};
+
+struct PatchOp : RecordedOp {
+    PatchOp(BASE_PARAMS, const SkBitmap* bitmap, const Res_png_9patch* patch)
+            : SUPER(PatchOp)
+            , bitmap(bitmap)
+            , patch(patch) {}
+    const SkBitmap* bitmap;
+    const Res_png_9patch* patch;
+};
+
+struct PathOp : RecordedOp {
+    PathOp(BASE_PARAMS, const SkPath* path)
+            : SUPER(PathOp)
+            , path(path) {}
+    const SkPath* path;
+};
+
+struct PointsOp : RecordedOp {
+    PointsOp(BASE_PARAMS, const float* points, const int floatCount)
+            : SUPER(PointsOp)
+            , points(points)
+            , floatCount(floatCount) {}
+    const float* points;
+    const int floatCount;
+};
+
 struct RectOp : RecordedOp {
     RectOp(BASE_PARAMS)
             : SUPER(RectOp) {}
 };
 
+struct RoundRectOp : RecordedOp {
+    RoundRectOp(BASE_PARAMS, float rx, float ry)
+            : SUPER(RoundRectOp)
+            , rx(rx)
+            , ry(ry) {}
+    const float rx;
+    const float ry;
+};
+
+struct RoundRectPropsOp : RecordedOp {
+    RoundRectPropsOp(const Matrix4& localMatrix, const Rect& localClipRect, const SkPaint* paint,
+            float* left, float* top, float* right, float* bottom, float *rx, float *ry)
+            : RecordedOp(RecordedOpId::RoundRectPropsOp, Rect(), localMatrix, localClipRect, paint)
+            , left(left)
+            , top(top)
+            , right(right)
+            , bottom(bottom)
+            , rx(rx)
+            , ry(ry) {}
+    const float* left;
+    const float* top;
+    const float* right;
+    const float* bottom;
+    const float* rx;
+    const float* ry;
+};
+
 /**
  * Real-time, dynamic-lit shadow.
  *
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 69c686e..1bf92be 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -237,29 +237,32 @@
             refPaint(&paint)));
 }
 
+static Rect calcBoundsOfPoints(const float* points, int floatCount) {
+    Rect unmappedBounds(points[0], points[1], points[0], points[1]);
+    for (int i = 2; i < floatCount; i += 2) {
+        unmappedBounds.expandToCover(points[i], points[i + 1]);
+    }
+    return unmappedBounds;
+}
+
 // Geometry
-void RecordingCanvas::drawPoints(const float* points, int count, const SkPaint& paint) {
-    LOG_ALWAYS_FATAL("TODO!");
+void RecordingCanvas::drawPoints(const float* points, int floatCount, const SkPaint& paint) {
+    if (floatCount < 2) return;
+    floatCount &= ~0x1; // round down to nearest two
+
+    addOp(new (alloc()) PointsOp(
+            calcBoundsOfPoints(points, floatCount),
+            *mState.currentSnapshot()->transform,
+            mState.getRenderTargetClipBounds(),
+            refPaint(&paint), refBuffer<float>(points, floatCount), floatCount));
 }
 
 void RecordingCanvas::drawLines(const float* points, int floatCount, const SkPaint& paint) {
     if (floatCount < 4) return;
     floatCount &= ~0x3; // round down to nearest four
 
-    Rect unmappedBounds(points[0], points[1], points[0], points[1]);
-    for (int i = 2; i < floatCount; i += 2) {
-        unmappedBounds.left = std::min(unmappedBounds.left, points[i]);
-        unmappedBounds.right = std::max(unmappedBounds.right, points[i]);
-        unmappedBounds.top = std::min(unmappedBounds.top, points[i + 1]);
-        unmappedBounds.bottom = std::max(unmappedBounds.bottom, points[i + 1]);
-    }
-
-    // since anything AA stroke with less than 1.0 pixel width is drawn with an alpha-reduced
-    // 1.0 stroke, treat 1.0 as minimum.
-    unmappedBounds.outset(std::max(paint.getStrokeWidth(), 1.0f) * 0.5f);
-
     addOp(new (alloc()) LinesOp(
-            unmappedBounds,
+            calcBoundsOfPoints(points, floatCount),
             *mState.currentSnapshot()->transform,
             mState.getRenderTargetClipBounds(),
             refPaint(&paint), refBuffer<float>(points, floatCount), floatCount));
@@ -333,20 +336,80 @@
 }
 void RecordingCanvas::drawRoundRect(float left, float top, float right, float bottom,
             float rx, float ry, const SkPaint& paint) {
-    LOG_ALWAYS_FATAL("TODO!");
+    addOp(new (alloc()) RoundRectOp(
+            Rect(left, top, right, bottom),
+            *(mState.currentSnapshot()->transform),
+            mState.getRenderTargetClipBounds(),
+            refPaint(&paint), rx, ry));
 }
+
+void RecordingCanvas::drawRoundRect(
+        CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
+        CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
+        CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
+        CanvasPropertyPaint* paint) {
+    mDisplayList->ref(left);
+    mDisplayList->ref(top);
+    mDisplayList->ref(right);
+    mDisplayList->ref(bottom);
+    mDisplayList->ref(rx);
+    mDisplayList->ref(ry);
+    mDisplayList->ref(paint);
+    refBitmapsInShader(paint->value.getShader());
+    addOp(new (alloc()) RoundRectPropsOp(
+            *(mState.currentSnapshot()->transform),
+            mState.getRenderTargetClipBounds(),
+            &paint->value,
+            &left->value, &top->value, &right->value, &bottom->value,
+            &rx->value, &ry->value));
+}
+
 void RecordingCanvas::drawCircle(float x, float y, float radius, const SkPaint& paint) {
-    LOG_ALWAYS_FATAL("TODO!");
+    // TODO: move to Canvas.h
+    if (radius <= 0) return;
+    drawOval(x - radius, y - radius, x + radius, y + radius, paint);
 }
+
+void RecordingCanvas::drawCircle(
+        CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
+        CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) {
+    mDisplayList->ref(x);
+    mDisplayList->ref(y);
+    mDisplayList->ref(radius);
+    mDisplayList->ref(paint);
+    refBitmapsInShader(paint->value.getShader());
+    addOp(new (alloc()) CirclePropsOp(
+            *(mState.currentSnapshot()->transform),
+            mState.getRenderTargetClipBounds(),
+            &paint->value,
+            &x->value, &y->value, &radius->value));
+}
+
+
 void RecordingCanvas::drawOval(float left, float top, float right, float bottom, const SkPaint& paint) {
-    LOG_ALWAYS_FATAL("TODO!");
+    addOp(new (alloc()) OvalOp(
+            Rect(left, top, right, bottom),
+            *(mState.currentSnapshot()->transform),
+            mState.getRenderTargetClipBounds(),
+            refPaint(&paint)));
 }
+
 void RecordingCanvas::drawArc(float left, float top, float right, float bottom,
-            float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) {
-    LOG_ALWAYS_FATAL("TODO!");
+        float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) {
+    addOp(new (alloc()) ArcOp(
+            Rect(left, top, right, bottom),
+            *(mState.currentSnapshot()->transform),
+            mState.getRenderTargetClipBounds(),
+            refPaint(&paint),
+            startAngle, sweepAngle, useCenter));
 }
+
 void RecordingCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
-    LOG_ALWAYS_FATAL("TODO!");
+    addOp(new (alloc()) PathOp(
+            Rect(path.getBounds()),
+            *(mState.currentSnapshot()->transform),
+            mState.getRenderTargetClipBounds(),
+            refPaint(&paint), refPath(&path)));
 }
 
 // Bitmap-based
@@ -378,6 +441,7 @@
         restore();
     }
 }
+
 void RecordingCanvas::drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
             float srcRight, float srcBottom, float dstLeft, float dstTop,
             float dstRight, float dstBottom, const SkPaint* paint) {
@@ -392,17 +456,35 @@
         drawBitmap(&bitmap, paint);
         restore();
     } else {
-        LOG_ALWAYS_FATAL("TODO!");
+        addOp(new (alloc()) BitmapRectOp(
+                Rect(dstLeft, dstTop, dstRight, dstBottom),
+                *(mState.currentSnapshot()->transform),
+                mState.getRenderTargetClipBounds(),
+                refPaint(paint), refBitmap(bitmap),
+                Rect(srcLeft, srcTop, srcRight, srcBottom)));
     }
 }
+
 void RecordingCanvas::drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
             const float* vertices, const int* colors, const SkPaint* paint) {
-    LOG_ALWAYS_FATAL("TODO!");
+    int vertexCount = (meshWidth + 1) * (meshHeight + 1);
+    addOp(new (alloc()) BitmapMeshOp(
+            calcBoundsOfPoints(vertices, vertexCount * 2),
+            *(mState.currentSnapshot()->transform),
+            mState.getRenderTargetClipBounds(),
+            refPaint(paint), refBitmap(bitmap), meshWidth, meshHeight,
+            refBuffer<float>(vertices, vertexCount * 2), // 2 floats per vertex
+            refBuffer<int>(colors, vertexCount))); // 1 color per vertex
 }
-void RecordingCanvas::drawNinePatch(const SkBitmap& bitmap, const android::Res_png_9patch& chunk,
+
+void RecordingCanvas::drawNinePatch(const SkBitmap& bitmap, const android::Res_png_9patch& patch,
             float dstLeft, float dstTop, float dstRight, float dstBottom,
             const SkPaint* paint) {
-    LOG_ALWAYS_FATAL("TODO!");
+    addOp(new (alloc()) PatchOp(
+            Rect(dstLeft, dstTop, dstRight, dstBottom),
+            *(mState.currentSnapshot()->transform),
+            mState.getRenderTargetClipBounds(),
+            refPaint(paint), refBitmap(bitmap), refPatch(&patch)));
 }
 
 // Text
@@ -413,6 +495,7 @@
     glyphs = refBuffer<glyph_t>(glyphs, glyphCount);
     positions = refBuffer<float>(positions, glyphCount * 2);
 
+    // TODO: either must account for text shadow in bounds, or record separate ops for text shadows
     addOp(new (alloc()) TextOp(
             Rect(boundsLeft, boundsTop, boundsRight, boundsBottom),
             *(mState.currentSnapshot()->transform),
@@ -423,7 +506,6 @@
 
 void RecordingCanvas::drawTextOnPath(const uint16_t* glyphs, int count, const SkPath& path,
             float hOffset, float vOffset, const SkPaint& paint) {
-    // NOTE: can't use refPaint() directly, since it forces left alignment
     LOG_ALWAYS_FATAL("TODO!");
 }
 
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 6d0e9e0..6fbaa8a 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -69,6 +69,17 @@
     virtual GLuint getTargetFbo() const override { return -1; }
 
 // ----------------------------------------------------------------------------
+// HWUI Canvas draw operations
+// ----------------------------------------------------------------------------
+
+    void drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
+            CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
+            CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
+            CanvasPropertyPaint* paint);
+    void drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
+            CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint);
+
+// ----------------------------------------------------------------------------
 // android/graphics/Canvas interface
 // ----------------------------------------------------------------------------
     virtual SkCanvas* asSkCanvas() override;
@@ -140,13 +151,13 @@
         float points[2] = { x, y };
         drawPoints(points, 2, paint);
     }
-    virtual void drawPoints(const float* points, int count, const SkPaint& paint) override;
+    virtual void drawPoints(const float* points, int floatCount, const SkPaint& paint) override;
     virtual void drawLine(float startX, float startY, float stopX, float stopY,
             const SkPaint& paint) override {
         float points[4] = { startX, startY, stopX, stopY };
         drawLines(points, 4, paint);
     }
-    virtual void drawLines(const float* points, int count, const SkPaint& paint) override;
+    virtual void drawLines(const float* points, int floatCount, const SkPaint& paint) override;
     virtual void drawRect(float left, float top, float right, float bottom, const SkPaint& paint) override;
     virtual void drawRegion(const SkRegion& region, const SkPaint& paint) override;
     virtual void drawRoundRect(float left, float top, float right, float bottom,
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index 472aad7..30c925c 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -253,7 +253,18 @@
         bottom = ceilf(bottom);
     }
 
-    void expandToCoverVertex(float x, float y) {
+    /*
+     * Similar to unionWith, except this makes the assumption that both rects are non-empty
+     * to avoid both emptiness checks.
+     */
+    void expandToCover(const Rect& other) {
+        left = std::min(left, other.left);
+        top = std::min(top, other.top);
+        right = std::max(right, other.right);
+        bottom = std::max(bottom, other.bottom);
+    }
+
+    void expandToCover(float x, float y) {
         left = std::min(left, x);
         top = std::min(top, y);
         right = std::max(right, x);
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index 4bcd96d..1c544b9 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -120,16 +120,16 @@
 
 class AutoTexture {
 public:
-    AutoTexture(const Texture* texture): mTexture(texture) { }
+    AutoTexture(const Texture* texture)
+            : texture(texture) {}
     ~AutoTexture() {
-        if (mTexture && mTexture->cleanup) {
-            mTexture->deleteTexture();
-            delete mTexture;
+        if (texture && texture->cleanup) {
+            texture->deleteTexture();
+            delete texture;
         }
     }
 
-private:
-    const Texture* mTexture;
+    const Texture *const texture;
 }; // class AutoTexture
 
 }; // namespace uirenderer
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index a6c72a3..21901cf 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -138,7 +138,7 @@
 // in the cache (and is thus added to the cache)
 Texture* TextureCache::getCachedTexture(const SkBitmap* bitmap, AtlasUsageType atlasUsageType) {
     if (CC_LIKELY(mAssetAtlas != nullptr) && atlasUsageType == AtlasUsageType::Use) {
-        AssetAtlas::Entry* entry = mAssetAtlas->getEntry(bitmap);
+        AssetAtlas::Entry* entry = mAssetAtlas->getEntry(bitmap->pixelRef());
         if (CC_UNLIKELY(entry)) {
             return entry->texture;
         }
diff --git a/libs/hwui/VertexBuffer.h b/libs/hwui/VertexBuffer.h
index c0373ac..bdb5b7b 100644
--- a/libs/hwui/VertexBuffer.h
+++ b/libs/hwui/VertexBuffer.h
@@ -118,7 +118,7 @@
         TYPE* end = current + vertexCount;
         mBounds.set(current->x, current->y, current->x, current->y);
         for (; current < end; current++) {
-            mBounds.expandToCoverVertex(current->x, current->y);
+            mBounds.expandToCover(current->x, current->y);
         }
     }
 
diff --git a/libs/hwui/tests/macrobench/TestContext.cpp b/libs/hwui/tests/common/TestContext.cpp
similarity index 98%
rename from libs/hwui/tests/macrobench/TestContext.cpp
rename to libs/hwui/tests/common/TestContext.cpp
index ba763a8..146e735 100644
--- a/libs/hwui/tests/macrobench/TestContext.cpp
+++ b/libs/hwui/tests/common/TestContext.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "TestContext.h"
+#include "tests/common/TestContext.h"
 
 namespace android {
 namespace uirenderer {
diff --git a/libs/hwui/tests/macrobench/TestContext.h b/libs/hwui/tests/common/TestContext.h
similarity index 100%
rename from libs/hwui/tests/macrobench/TestContext.h
rename to libs/hwui/tests/common/TestContext.h
diff --git a/libs/hwui/tests/common/TestScene.cpp b/libs/hwui/tests/common/TestScene.cpp
new file mode 100644
index 0000000..02bcd47
--- /dev/null
+++ b/libs/hwui/tests/common/TestScene.cpp
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#include "tests/common/TestScene.h"
+
+namespace android {
+namespace uirenderer {
+namespace test {
+
+// Not a static global because we need to force the map to be constructed
+// before we try to add things to it.
+std::unordered_map<std::string, TestScene::Info>& TestScene::testMap() {
+    static std::unordered_map<std::string, TestScene::Info> testMap;
+    return testMap;
+}
+
+void TestScene::registerScene(const TestScene::Info& info) {
+    testMap()[info.name] = info;
+}
+
+} /* namespace test */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/tests/common/TestScene.h b/libs/hwui/tests/common/TestScene.h
index b5d8954..df8d194 100644
--- a/libs/hwui/tests/common/TestScene.h
+++ b/libs/hwui/tests/common/TestScene.h
@@ -16,6 +16,9 @@
 #ifndef TESTS_TESTSCENE_H
 #define TESTS_TESTSCENE_H
 
+#include <string>
+#include <unordered_map>
+
 namespace android {
 namespace uirenderer {
 class RenderNode;
@@ -32,9 +35,40 @@
 
 class TestScene {
 public:
+    struct Options {
+        int count = 0;
+    };
+
+    template <class T>
+    static test::TestScene* simpleCreateScene(const TestScene::Options&) {
+        return new T();
+    }
+
+    typedef test::TestScene* (*CreateScene)(const TestScene::Options&);
+
+    struct Info {
+        std::string name;
+        std::string description;
+        CreateScene createScene;
+    };
+
+    class Registrar {
+    public:
+        Registrar(const TestScene::Info& info) {
+            TestScene::registerScene(info);
+        }
+    private:
+        Registrar() = delete;
+        Registrar(const Registrar&) = delete;
+        Registrar& operator=(const Registrar&) = delete;
+    };
+
     virtual ~TestScene() {}
     virtual void createContent(int width, int height, TestCanvas& renderer) = 0;
     virtual void doFrame(int frameNr) = 0;
+
+    static std::unordered_map<std::string, Info>& testMap();
+    static void registerScene(const Info& info);
 };
 
 } // namespace test
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index 9c1c0b9..0af9939 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -103,10 +103,11 @@
         return snapshot;
     }
 
-    static SkBitmap createSkBitmap(int width, int height) {
+    static SkBitmap createSkBitmap(int width, int height,
+            SkColorType colorType = kN32_SkColorType) {
         SkBitmap bitmap;
         SkImageInfo info = SkImageInfo::Make(width, height,
-                kN32_SkColorType, kPremul_SkAlphaType);
+                colorType, kPremul_SkAlphaType);
         bitmap.setInfo(info);
         bitmap.allocPixels(info);
         return bitmap;
diff --git a/libs/hwui/tests/common/scenes/HwLayerAnimation.cpp b/libs/hwui/tests/common/scenes/HwLayerAnimation.cpp
index e316eca..c212df4 100644
--- a/libs/hwui/tests/common/scenes/HwLayerAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/HwLayerAnimation.cpp
@@ -18,11 +18,11 @@
 
 class HwLayerAnimation;
 
-static Benchmark _HwLayer(BenchmarkInfo{
+static TestScene::Registrar _HwLayer(TestScene::Info{
     "hwlayer",
     "A nested pair of nodes with LAYER_TYPE_HARDWARE set on each. "
     "Tests the hardware layer codepath.",
-    simpleCreateScene<HwLayerAnimation>
+    TestScene::simpleCreateScene<HwLayerAnimation>
 });
 
 class HwLayerAnimation : public TestScene {
diff --git a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
index 27adb12..43e247e 100644
--- a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
@@ -21,11 +21,11 @@
 
 class ListViewAnimation;
 
-static Benchmark _ListView(BenchmarkInfo{
+static TestScene::Registrar _ListView(TestScene::Info{
     "listview",
     "A mock ListView of scrolling content. Doesn't re-bind/re-record views as they are recycled, so"
     "won't upload much content (either glyphs, or bitmaps).",
-    simpleCreateScene<ListViewAnimation>
+    TestScene::simpleCreateScene<ListViewAnimation>
 });
 
 class ListViewAnimation : public TestScene {
@@ -62,7 +62,9 @@
         int cardIndexOffset = scrollPx / (cardSpacing + cardHeight);
         int pxOffset = -(scrollPx % (cardSpacing + cardHeight));
 
-        TestCanvas canvas(cardWidth, cardHeight);
+        TestCanvas canvas(
+                listView->stagingProperties().getWidth(),
+                listView->stagingProperties().getHeight());
         for (size_t ci = 0; ci < cards.size(); ci++) {
             // update card position
             auto card = cards[(ci + cardIndexOffset) % cards.size()];
@@ -121,9 +123,11 @@
             static SkBitmap filledBox = createBoxBitmap(true);
             static SkBitmap strokedBox = createBoxBitmap(false);
 
-            props.mutableOutline().setRoundRect(0, 0, cardWidth, cardHeight, dp(6), 1);
-            props.mutableOutline().setShouldClip(true);
-            canvas.drawColor(Color::White, SkXfermode::kSrcOver_Mode);
+            // TODO: switch to using round rect clipping, once merging correctly handles that
+            SkPaint roundRectPaint;
+            roundRectPaint.setAntiAlias(true);
+            roundRectPaint.setColor(Color::White);
+            canvas.drawRoundRect(0, 0, cardWidth, cardHeight, dp(6), dp(6), roundRectPaint);
 
             SkPaint textPaint;
             textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
diff --git a/libs/hwui/tests/common/scenes/OpPropAnimation.cpp b/libs/hwui/tests/common/scenes/OpPropAnimation.cpp
new file mode 100644
index 0000000..5dfb2b4
--- /dev/null
+++ b/libs/hwui/tests/common/scenes/OpPropAnimation.cpp
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+#include "TestSceneBase.h"
+#include "utils/Color.h"
+
+class OpPropAnimation;
+
+static TestScene::Registrar _Shapes(TestScene::Info{
+    "opprops",
+    "A minimal demonstration of CanvasProperty drawing operations.",
+    TestScene::simpleCreateScene<OpPropAnimation>
+});
+
+class OpPropAnimation : public TestScene {
+public:
+    sp<CanvasPropertyPaint> mPaint = new CanvasPropertyPaint(SkPaint());
+
+    sp<CanvasPropertyPrimitive> mRoundRectLeft = new CanvasPropertyPrimitive(0);
+    sp<CanvasPropertyPrimitive> mRoundRectTop = new CanvasPropertyPrimitive(0);
+    sp<CanvasPropertyPrimitive> mRoundRectRight = new CanvasPropertyPrimitive(0);
+    sp<CanvasPropertyPrimitive> mRoundRectBottom = new CanvasPropertyPrimitive(0);
+    sp<CanvasPropertyPrimitive> mRoundRectRx = new CanvasPropertyPrimitive(0);
+    sp<CanvasPropertyPrimitive> mRoundRectRy = new CanvasPropertyPrimitive(0);
+
+    sp<CanvasPropertyPrimitive> mCircleX = new CanvasPropertyPrimitive(0);
+    sp<CanvasPropertyPrimitive> mCircleY = new CanvasPropertyPrimitive(0);
+    sp<CanvasPropertyPrimitive> mCircleRadius = new CanvasPropertyPrimitive(0);
+
+    sp<RenderNode> content;
+    void createContent(int width, int height, TestCanvas& canvas) override {
+        content = TestUtils::createNode(0, 0, width, height,
+                [this, width, height](RenderProperties& props, TestCanvas& canvas) {
+            mPaint->value.setAntiAlias(true);
+            mPaint->value.setColor(Color::Blue_500);
+
+            mRoundRectRight->value = width / 2;
+            mRoundRectBottom->value = height / 2;
+
+            mCircleX->value = width * 0.75;
+            mCircleY->value = height * 0.75;
+
+            canvas.drawColor(Color::White, SkXfermode::Mode::kSrcOver_Mode);
+            canvas.drawRoundRect(mRoundRectLeft.get(), mRoundRectTop.get(),
+                    mRoundRectRight.get(), mRoundRectBottom.get(),
+                    mRoundRectRx.get(), mRoundRectRy.get(), mPaint.get());
+            canvas.drawCircle(mCircleX.get(), mCircleY.get(), mCircleRadius.get(), mPaint.get());
+        });
+        canvas.drawRenderNode(content.get());
+    }
+
+    void doFrame(int frameNr) override {
+        float value = (abs((frameNr % 200) - 100)) / 100.0f;
+        mRoundRectRx->value = dp(10) + value * dp(40);
+        mRoundRectRy->value = dp(10) + value * dp(80);
+        mCircleRadius->value = value * dp(200);
+        content->setPropertyFieldsDirty(RenderNode::GENERIC);
+    }
+};
diff --git a/libs/hwui/tests/common/scenes/OvalAnimation.cpp b/libs/hwui/tests/common/scenes/OvalAnimation.cpp
index 936aba1..082c628 100644
--- a/libs/hwui/tests/common/scenes/OvalAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/OvalAnimation.cpp
@@ -18,10 +18,10 @@
 
 class OvalAnimation;
 
-static Benchmark _Oval(BenchmarkInfo{
+static TestScene::Registrar _Oval(TestScene::Info{
     "oval",
     "Draws 1 oval.",
-    simpleCreateScene<OvalAnimation>
+    TestScene::simpleCreateScene<OvalAnimation>
 });
 
 class OvalAnimation : public TestScene {
diff --git a/libs/hwui/tests/common/scenes/PartialDamageAnimation.cpp b/libs/hwui/tests/common/scenes/PartialDamageAnimation.cpp
index c31ddd1..84265a4 100644
--- a/libs/hwui/tests/common/scenes/PartialDamageAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/PartialDamageAnimation.cpp
@@ -18,12 +18,12 @@
 
 class PartialDamageAnimation;
 
-static Benchmark _PartialDamage(BenchmarkInfo{
+static TestScene::Registrar _PartialDamage(TestScene::Info{
     "partialdamage",
     "Tests the partial invalidation path. Draws a grid of rects and animates 1 "
     "of them, should be low CPU & GPU load if EGL_EXT_buffer_age or "
     "EGL_KHR_partial_update is supported by the device & are enabled in hwui.",
-    simpleCreateScene<PartialDamageAnimation>
+    TestScene::simpleCreateScene<PartialDamageAnimation>
 });
 
 class PartialDamageAnimation : public TestScene {
diff --git a/libs/hwui/tests/common/scenes/RecentsAnimation.cpp b/libs/hwui/tests/common/scenes/RecentsAnimation.cpp
index 5d4ef96..6509edd 100644
--- a/libs/hwui/tests/common/scenes/RecentsAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/RecentsAnimation.cpp
@@ -19,11 +19,11 @@
 
 class RecentsAnimation;
 
-static Benchmark _Recents(BenchmarkInfo{
+static TestScene::Registrar _Recents(TestScene::Info{
     "recents",
     "A recents-like scrolling list of textures. "
     "Consists of updating a texture every frame",
-    simpleCreateScene<RecentsAnimation>
+    TestScene::simpleCreateScene<RecentsAnimation>
 });
 
 class RecentsAnimation : public TestScene {
diff --git a/libs/hwui/tests/common/scenes/RectGridAnimation.cpp b/libs/hwui/tests/common/scenes/RectGridAnimation.cpp
index a1f04d6..a9293ab 100644
--- a/libs/hwui/tests/common/scenes/RectGridAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/RectGridAnimation.cpp
@@ -19,11 +19,11 @@
 
 class RectGridAnimation;
 
-static Benchmark _RectGrid(BenchmarkInfo{
+static TestScene::Registrar _RectGrid(TestScene::Info{
     "rectgrid",
     "A dense grid of 1x1 rects that should visually look like a single rect. "
     "Low CPU/GPU load.",
-    simpleCreateScene<RectGridAnimation>
+    TestScene::simpleCreateScene<RectGridAnimation>
 });
 
 class RectGridAnimation : public TestScene {
diff --git a/libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp b/libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp
index c73e97b..78fcd8b 100644
--- a/libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp
@@ -18,11 +18,11 @@
 
 class SaveLayerAnimation;
 
-static Benchmark _SaveLayer(BenchmarkInfo{
+static TestScene::Registrar _SaveLayer(TestScene::Info{
     "savelayer",
     "A nested pair of clipped saveLayer operations. "
     "Tests the clipped saveLayer codepath. Draws content into offscreen buffers and back again.",
-    simpleCreateScene<SaveLayerAnimation>
+    TestScene::simpleCreateScene<SaveLayerAnimation>
 });
 
 class SaveLayerAnimation : public TestScene {
diff --git a/libs/hwui/tests/common/scenes/ShadowGrid2Animation.cpp b/libs/hwui/tests/common/scenes/ShadowGrid2Animation.cpp
index 26c86aa..d3249b8 100644
--- a/libs/hwui/tests/common/scenes/ShadowGrid2Animation.cpp
+++ b/libs/hwui/tests/common/scenes/ShadowGrid2Animation.cpp
@@ -18,11 +18,11 @@
 
 class ShadowGrid2Animation;
 
-static Benchmark _ShadowGrid2(BenchmarkInfo{
+static TestScene::Registrar _ShadowGrid2(TestScene::Info{
     "shadowgrid2",
     "A dense grid of rounded rects that cast a shadow. This is a higher CPU load "
     "variant of shadowgrid. Very high CPU load, high GPU load.",
-    simpleCreateScene<ShadowGrid2Animation>
+    TestScene::simpleCreateScene<ShadowGrid2Animation>
 });
 
 class ShadowGrid2Animation : public TestScene {
diff --git a/libs/hwui/tests/common/scenes/ShadowGridAnimation.cpp b/libs/hwui/tests/common/scenes/ShadowGridAnimation.cpp
index ee3c590..5ffedf0 100644
--- a/libs/hwui/tests/common/scenes/ShadowGridAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/ShadowGridAnimation.cpp
@@ -18,11 +18,11 @@
 
 class ShadowGridAnimation;
 
-static Benchmark _ShadowGrid(BenchmarkInfo{
+static TestScene::Registrar _ShadowGrid(TestScene::Info{
     "shadowgrid",
     "A grid of rounded rects that cast a shadow. Simplified scenario of an "
     "Android TV-style launcher interface. High CPU/GPU load.",
-    simpleCreateScene<ShadowGridAnimation>
+    TestScene::simpleCreateScene<ShadowGridAnimation>
 });
 
 class ShadowGridAnimation : public TestScene {
diff --git a/libs/hwui/tests/common/scenes/ShapeAnimation.cpp b/libs/hwui/tests/common/scenes/ShapeAnimation.cpp
new file mode 100644
index 0000000..0cba344
--- /dev/null
+++ b/libs/hwui/tests/common/scenes/ShapeAnimation.cpp
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+#include "TestSceneBase.h"
+#include "utils/Color.h"
+
+#include <cstdio>
+
+class ShapeAnimation;
+
+static TestScene::Registrar _Shapes(TestScene::Info{
+    "shapes",
+    "A grid of shape drawing test cases.",
+    TestScene::simpleCreateScene<ShapeAnimation>
+});
+
+class ShapeAnimation : public TestScene {
+public:
+    sp<RenderNode> card;
+    void createContent(int width, int height, TestCanvas& canvas) override {
+        card = TestUtils::createNode(0, 0, width, height,
+                [width](RenderProperties& props, TestCanvas& canvas) {
+            std::function<void(TestCanvas&, float, const SkPaint&)> ops[] = {
+                [](TestCanvas& canvas, float size, const SkPaint& paint) {
+                    canvas.drawArc(0, 0, size, size, 50, 189, true, paint);
+                },
+                [](TestCanvas& canvas, float size, const SkPaint& paint) {
+                    canvas.drawOval(0, 0, size, size, paint);
+                },
+                [](TestCanvas& canvas, float size, const SkPaint& paint) {
+                    SkPath diamondPath;
+                    diamondPath.moveTo(size / 2, 0);
+                    diamondPath.lineTo(size, size / 2);
+                    diamondPath.lineTo(size / 2, size);
+                    diamondPath.lineTo(0, size / 2);
+                    diamondPath.close();
+                    canvas.drawPath(diamondPath, paint);
+                },
+                [](TestCanvas& canvas, float size, const SkPaint& paint) {
+                    float data[] = {0, 0, size, size, 0, size, size, 0 };
+                    canvas.drawLines(data, sizeof(data) / sizeof(float), paint);
+                },
+                [](TestCanvas& canvas, float size, const SkPaint& paint) {
+                    float data[] = {0, 0, size, size, 0, size, size, 0 };
+                    canvas.drawPoints(data, sizeof(data) / sizeof(float), paint);
+                },
+                [](TestCanvas& canvas, float size, const SkPaint& paint) {
+                    canvas.drawRect(0, 0, size, size, paint);
+                },
+                [](TestCanvas& canvas, float size, const SkPaint& paint) {
+                    float rad = size / 4;
+                    canvas.drawRoundRect(0, 0, size, size, rad, rad, paint);
+                }
+            };
+            float cellSpace = dp(4);
+            float cellSize = floorf(width / 7 - cellSpace);
+
+            // each combination of strokeWidth + style gets a column
+            int outerCount = canvas.save(SkCanvas::kMatrixClip_SaveFlag);
+            SkPaint paint;
+            paint.setAntiAlias(true);
+            SkPaint::Style styles[] = {
+                    SkPaint::kStroke_Style, SkPaint::kFill_Style, SkPaint::kStrokeAndFill_Style };
+            for (auto style : styles) {
+                paint.setStyle(style);
+                for (auto strokeWidth : { 0.0f, 0.5f, 8.0f }) {
+                    paint.setStrokeWidth(strokeWidth);
+                    // fill column with each op
+                    int middleCount = canvas.save(SkCanvas::kMatrixClip_SaveFlag);
+                    for (auto op : ops) {
+                        int innerCount = canvas.save(SkCanvas::kMatrixClip_SaveFlag);
+                        canvas.clipRect(0, 0, cellSize, cellSize, SkRegion::kIntersect_Op);
+                        canvas.drawColor(Color::White, SkXfermode::Mode::kSrcOver_Mode);
+                        op(canvas, cellSize, paint);
+                        canvas.restoreToCount(innerCount);
+                        canvas.translate(cellSize + cellSpace, 0);
+                    }
+                    canvas.restoreToCount(middleCount);
+                    canvas.translate(0, cellSize + cellSpace);
+                }
+            }
+            canvas.restoreToCount(outerCount);
+        });
+        canvas.drawColor(Color::Grey_500, SkXfermode::Mode::kSrcOver_Mode);
+        canvas.drawRenderNode(card.get());
+    }
+
+    void doFrame(int frameNr) override {
+        card->mutateStagingProperties().setTranslationY(frameNr % 150);
+        card->setPropertyFieldsDirty(RenderNode::Y);
+    }
+};
diff --git a/libs/hwui/tests/common/scenes/TestSceneBase.h b/libs/hwui/tests/common/scenes/TestSceneBase.h
index 8a24149..ac78124 100644
--- a/libs/hwui/tests/common/scenes/TestSceneBase.h
+++ b/libs/hwui/tests/common/scenes/TestSceneBase.h
@@ -19,8 +19,7 @@
 #include "DisplayListCanvas.h"
 #include "RecordingCanvas.h"
 #include "RenderNode.h"
-#include "tests/macrobench/Benchmark.h"
-#include "tests/macrobench/TestContext.h"
+#include "tests/common/TestContext.h"
 #include "tests/common/TestScene.h"
 #include "tests/common/TestUtils.h"
 
diff --git a/libs/hwui/tests/macrobench/Benchmark.h b/libs/hwui/tests/macrobench/Benchmark.h
deleted file mode 100644
index aad8eb3..0000000
--- a/libs/hwui/tests/macrobench/Benchmark.h
+++ /dev/null
@@ -1,61 +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.
- */
-#ifndef TESTS_BENCHMARK_H
-#define TESTS_BENCHMARK_H
-
-#include "tests/common/TestScene.h"
-
-#include <string>
-#include <vector>
-
-namespace android {
-namespace uirenderer {
-
-struct BenchmarkOptions {
-    int count;
-};
-
-typedef test::TestScene* (*CreateScene)(const BenchmarkOptions&);
-
-template <class T>
-test::TestScene* simpleCreateScene(const BenchmarkOptions&) {
-    return new T();
-}
-
-struct BenchmarkInfo {
-    std::string name;
-    std::string description;
-    CreateScene createScene;
-};
-
-class Benchmark {
-public:
-    Benchmark(const BenchmarkInfo& info) {
-        registerBenchmark(info);
-    }
-
-private:
-    Benchmark() = delete;
-    Benchmark(const Benchmark&) = delete;
-    Benchmark& operator=(const Benchmark&) = delete;
-
-    static void registerBenchmark(const BenchmarkInfo& info);
-};
-
-} /* namespace uirenderer */
-} /* namespace android */
-
-#endif /* TESTS_BENCHMARK_H */
diff --git a/libs/hwui/tests/macrobench/TestSceneRunner.cpp b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
index 1e1c6a1..8261220 100644
--- a/libs/hwui/tests/macrobench/TestSceneRunner.cpp
+++ b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
@@ -15,9 +15,9 @@
  */
 
 #include "AnimationContext.h"
-#include "Benchmark.h"
 #include "RenderNode.h"
-#include "TestContext.h"
+#include "tests/common/TestContext.h"
+#include "tests/common/TestScene.h"
 #include "tests/common/scenes/TestSceneBase.h"
 #include "renderthread/RenderProxy.h"
 #include "renderthread/RenderTask.h"
@@ -38,7 +38,7 @@
     }
 };
 
-void run(const BenchmarkInfo& info, const BenchmarkOptions& opts) {
+void run(const TestScene::Info& info, const TestScene::Options& opts) {
     // Switch to the real display
     gDisplay = getBuiltInDisplay();
 
diff --git a/libs/hwui/tests/macrobench/main.cpp b/libs/hwui/tests/macrobench/main.cpp
index 48566e8..619713c 100644
--- a/libs/hwui/tests/macrobench/main.cpp
+++ b/libs/hwui/tests/macrobench/main.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "Benchmark.h"
+#include "tests/common/TestScene.h"
 
 #include "protos/hwui.pb.h"
 
@@ -27,23 +27,13 @@
 
 using namespace android;
 using namespace android::uirenderer;
-
-// Not a static global because we need to force the map to be constructed
-// before we try to add things to it.
-std::unordered_map<std::string, BenchmarkInfo>& testMap() {
-    static std::unordered_map<std::string, BenchmarkInfo> testMap;
-    return testMap;
-}
-
-void Benchmark::registerBenchmark(const BenchmarkInfo& info) {
-    testMap()[info.name] = info;
-}
+using namespace android::uirenderer::test;
 
 static int gFrameCount = 150;
 static int gRepeatCount = 1;
-static std::vector<BenchmarkInfo> gRunTests;
+static std::vector<TestScene::Info> gRunTests;
 
-void run(const BenchmarkInfo& info, const BenchmarkOptions& opts);
+void run(const TestScene::Info& info, const TestScene::Options& opts);
 
 static void printHelp() {
     printf("\
@@ -59,7 +49,7 @@
 
 static void listTests() {
     printf("Tests: \n");
-    for (auto&& test : testMap()) {
+    for (auto&& test : TestScene::testMap()) {
         auto&& info = test.second;
         const char* col1 = info.name.c_str();
         int dlen = info.description.length();
@@ -168,8 +158,8 @@
     if (optind < argc) {
         do {
             const char* test = argv[optind++];
-            auto pos = testMap().find(test);
-            if (pos == testMap().end()) {
+            auto pos = TestScene::testMap().find(test);
+            if (pos == TestScene::testMap().end()) {
                 fprintf(stderr, "Unknown test '%s'\n", test);
                 exit(EXIT_FAILURE);
             } else {
@@ -177,14 +167,14 @@
             }
         } while (optind < argc);
     } else {
-        gRunTests.push_back(testMap()["shadowgrid"]);
+        gRunTests.push_back(TestScene::testMap()["shadowgrid"]);
     }
 }
 
 int main(int argc, char* argv[]) {
     parseOptions(argc, argv);
 
-    BenchmarkOptions opts;
+    TestScene::Options opts;
     opts.count = gFrameCount;
     for (int i = 0; i < gRepeatCount; i++) {
         for (auto&& test : gRunTests) {
diff --git a/libs/hwui/tests/microbench/OpReordererBench.cpp b/libs/hwui/tests/microbench/OpReordererBench.cpp
index 406bfcc..6bfe5a9 100644
--- a/libs/hwui/tests/microbench/OpReordererBench.cpp
+++ b/libs/hwui/tests/microbench/OpReordererBench.cpp
@@ -23,14 +23,18 @@
 #include "OpReorderer.h"
 #include "RecordedOp.h"
 #include "RecordingCanvas.h"
+#include "tests/common/TestContext.h"
+#include "tests/common/TestScene.h"
 #include "tests/common/TestUtils.h"
 #include "Vector.h"
-#include "microbench/MicroBench.h"
+#include "tests/microbench/MicroBench.h"
 
 #include <vector>
 
 using namespace android;
 using namespace android::uirenderer;
+using namespace android::uirenderer::renderthread;
+using namespace android::uirenderer::test;
 
 const LayerUpdateQueue sEmptyLayerUpdateQueue;
 const Vector3 sLightCenter = {100, 100, 100};
@@ -71,7 +75,7 @@
 
 BENCHMARK_NO_ARG(BM_OpReorderer_deferAndRender);
 void BM_OpReorderer_deferAndRender::Run(int iters) {
-    TestUtils::runOnRenderThread([this, iters](renderthread::RenderThread& thread) {
+    TestUtils::runOnRenderThread([this, iters](RenderThread& thread) {
         auto nodes = createTestNodeList();
         BakedOpRenderer::LightInfo lightInfo = {50.0f, 128, 128 };
 
@@ -90,3 +94,67 @@
         StopBenchmarkTiming();
     });
 }
+
+static std::vector<sp<RenderNode>> getSyncedSceneNodes(const char* sceneName) {
+    gDisplay = getBuiltInDisplay(); // switch to real display if present
+
+    TestContext testContext;
+    TestScene::Options opts;
+    std::unique_ptr<TestScene> scene(TestScene::testMap()[sceneName].createScene(opts));
+
+    sp<RenderNode> rootNode = TestUtils::createNode(0, 0, gDisplay.w, gDisplay.h,
+                [&scene](RenderProperties& props, TestCanvas& canvas) {
+            scene->createContent(gDisplay.w, gDisplay.h, canvas);
+    });
+
+    TestUtils::syncHierarchyPropertiesAndDisplayList(rootNode);
+    std::vector<sp<RenderNode>> nodes;
+    nodes.emplace_back(rootNode);
+    return nodes;
+}
+
+static void benchDeferScene(testing::Benchmark& benchmark, int iters, const char* sceneName) {
+    auto nodes = getSyncedSceneNodes(sceneName);
+    benchmark.StartBenchmarkTiming();
+    for (int i = 0; i < iters; i++) {
+        OpReorderer reorderer(sEmptyLayerUpdateQueue,
+                SkRect::MakeWH(gDisplay.w, gDisplay.h), gDisplay.w, gDisplay.h,
+                nodes, sLightCenter);
+        MicroBench::DoNotOptimize(&reorderer);
+    }
+    benchmark.StopBenchmarkTiming();
+}
+
+static void benchDeferAndRenderScene(testing::Benchmark& benchmark,
+        int iters, const char* sceneName) {
+    TestUtils::runOnRenderThread([&benchmark, iters, sceneName](RenderThread& thread) {
+        auto nodes = getSyncedSceneNodes(sceneName);
+        BakedOpRenderer::LightInfo lightInfo = {50.0f, 128, 128 }; // TODO!
+
+        RenderState& renderState = thread.renderState();
+        Caches& caches = Caches::getInstance();
+
+        benchmark.StartBenchmarkTiming();
+        for (int i = 0; i < iters; i++) {
+            OpReorderer reorderer(sEmptyLayerUpdateQueue,
+                    SkRect::MakeWH(gDisplay.w, gDisplay.h), gDisplay.w, gDisplay.h,
+                    nodes, sLightCenter);
+
+            BakedOpRenderer renderer(caches, renderState, true, lightInfo);
+            reorderer.replayBakedOps<BakedOpDispatcher>(renderer);
+            MicroBench::DoNotOptimize(&renderer);
+        }
+        benchmark.StopBenchmarkTiming();
+    });
+}
+
+BENCHMARK_NO_ARG(BM_OpReorderer_listview_defer);
+void BM_OpReorderer_listview_defer::Run(int iters) {
+    benchDeferScene(*this, iters, "listview");
+}
+
+BENCHMARK_NO_ARG(BM_OpReorderer_listview_deferAndRender);
+void BM_OpReorderer_listview_deferAndRender::Run(int iters) {
+    benchDeferAndRenderScene(*this, iters, "listview");
+}
+
diff --git a/libs/hwui/tests/unit/BakedOpStateTests.cpp b/libs/hwui/tests/unit/BakedOpStateTests.cpp
index de14abf..8321ff9 100644
--- a/libs/hwui/tests/unit/BakedOpStateTests.cpp
+++ b/libs/hwui/tests/unit/BakedOpStateTests.cpp
@@ -23,41 +23,130 @@
 namespace android {
 namespace uirenderer {
 
-TEST(ResolvedRenderState, resolution) {
-    Matrix4 identity;
-    identity.loadIdentity();
-
+TEST(ResolvedRenderState, construct) {
     Matrix4 translate10x20;
     translate10x20.loadTranslate(10, 20, 0);
 
     SkPaint paint;
-    RectOp recordedOp(Rect(30, 40, 100, 200), translate10x20, Rect(0, 0, 100, 200), &paint);
+    RectOp recordedOp(Rect(30, 40, 100, 200), translate10x20, Rect(100, 200), &paint);
     {
         // recorded with transform, no parent transform
-        auto parentSnapshot = TestUtils::makeSnapshot(identity, Rect(0, 0, 100, 200));
-        ResolvedRenderState state(*parentSnapshot, recordedOp);
+        auto parentSnapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(100, 200));
+        ResolvedRenderState state(*parentSnapshot, recordedOp, false);
         EXPECT_MATRIX_APPROX_EQ(state.transform, translate10x20);
-        EXPECT_EQ(state.clipRect, Rect(0, 0, 100, 200));
-        EXPECT_EQ(state.clippedBounds, Rect(40, 60, 100, 200)); // translated and also clipped
+        EXPECT_EQ(Rect(0, 0, 100, 200), state.clipRect);
+        EXPECT_EQ(Rect(40, 60, 100, 200), state.clippedBounds); // translated and also clipped
+        EXPECT_EQ(OpClipSideFlags::Right | OpClipSideFlags::Bottom, state.clipSideFlags);
     }
     {
         // recorded with transform and parent transform
-        auto parentSnapshot = TestUtils::makeSnapshot(translate10x20, Rect(0, 0, 100, 200));
-        ResolvedRenderState state(*parentSnapshot, recordedOp);
+        auto parentSnapshot = TestUtils::makeSnapshot(translate10x20, Rect(100, 200));
+        ResolvedRenderState state(*parentSnapshot, recordedOp, false);
 
         Matrix4 expectedTranslate;
         expectedTranslate.loadTranslate(20, 40, 0);
-        EXPECT_MATRIX_APPROX_EQ(state.transform, expectedTranslate);
+        EXPECT_MATRIX_APPROX_EQ(expectedTranslate, state.transform);
 
         // intersection of parent & transformed child clip
-        EXPECT_EQ(state.clipRect, Rect(10, 20, 100, 200));
+        EXPECT_EQ(Rect(10, 20, 100, 200), state.clipRect);
 
         // translated and also clipped
-        EXPECT_EQ(state.clippedBounds, Rect(50, 80, 100, 200));
+        EXPECT_EQ(Rect(50, 80, 100, 200), state.clippedBounds);
+        EXPECT_EQ(OpClipSideFlags::Right | OpClipSideFlags::Bottom, state.clipSideFlags);
     }
 }
 
-TEST(BakedOpState, constructAndReject) {
+const float HAIRLINE = 0.0f;
+
+// Note: bounds will be conservative, but not precise for non-hairline
+// - use approx bounds checks for these
+const float SEMI_HAIRLINE = 0.3f;
+
+struct StrokeTestCase {
+    float scale;
+    float strokeWidth;
+    const std::function<void(const ResolvedRenderState&)> validator;
+};
+
+const static StrokeTestCase sStrokeTestCases[] = {
+    {
+        1, HAIRLINE, [](const ResolvedRenderState& state) {
+            EXPECT_EQ(Rect(49.5f, 49.5f, 150.5f, 150.5f), state.clippedBounds);
+        }
+    },
+    {
+        1, SEMI_HAIRLINE, [](const ResolvedRenderState& state) {
+            EXPECT_TRUE(state.clippedBounds.contains(49.5f, 49.5f, 150.5f, 150.5f));
+            EXPECT_TRUE(Rect(49, 49, 151, 151).contains(state.clippedBounds));
+        }
+    },
+    {
+        1, 20, [](const ResolvedRenderState& state) {
+            EXPECT_EQ(Rect(40, 40, 160, 160), state.clippedBounds);
+        }
+    },
+
+    // 3x3 scale:
+    {
+        3, HAIRLINE, [](const ResolvedRenderState& state) {
+            EXPECT_EQ(Rect(149.5f, 149.5f, 200, 200), state.clippedBounds);
+            EXPECT_EQ(OpClipSideFlags::Right | OpClipSideFlags::Bottom, state.clipSideFlags);
+        }
+    },
+    {
+        3, SEMI_HAIRLINE, [](const ResolvedRenderState& state) {
+            EXPECT_TRUE(state.clippedBounds.contains(149.5f, 149.5f, 200, 200));
+            EXPECT_TRUE(Rect(149, 149, 200, 200).contains(state.clippedBounds));
+        }
+    },
+    {
+        3, 20, [](const ResolvedRenderState& state) {
+            EXPECT_TRUE(state.clippedBounds.contains(120, 120, 200, 200));
+            EXPECT_TRUE(Rect(119, 119, 200, 200).contains(state.clippedBounds));
+        }
+    },
+
+    // 0.5f x 0.5f scale
+    {
+        0.5f, HAIRLINE, [](const ResolvedRenderState& state) {
+            EXPECT_EQ(Rect(24.5f, 24.5f, 75.5f, 75.5f), state.clippedBounds);
+        }
+    },
+    {
+        0.5f, SEMI_HAIRLINE, [](const ResolvedRenderState& state) {
+            EXPECT_TRUE(state.clippedBounds.contains(24.5f, 24.5f, 75.5f, 75.5f));
+            EXPECT_TRUE(Rect(24, 24, 76, 76).contains(state.clippedBounds));
+        }
+    },
+    {
+        0.5f, 20, [](const ResolvedRenderState& state) {
+            EXPECT_TRUE(state.clippedBounds.contains(19.5f, 19.5f, 80.5f, 80.5f));
+            EXPECT_TRUE(Rect(19, 19, 81, 81).contains(state.clippedBounds));
+        }
+    }
+};
+
+TEST(ResolvedRenderState, construct_expandForStroke) {
+    // Loop over table of test cases and verify different combinations of stroke width and transform
+    for (auto&& testCase : sStrokeTestCases) {
+        SkPaint strokedPaint;
+        strokedPaint.setAntiAlias(true);
+        strokedPaint.setStyle(SkPaint::kStroke_Style);
+        strokedPaint.setStrokeWidth(testCase.strokeWidth);
+
+        RectOp recordedOp(Rect(50, 50, 150, 150),
+                Matrix4::identity(), Rect(200, 200), &strokedPaint);
+
+        Matrix4 snapshotMatrix;
+        snapshotMatrix.loadScale(testCase.scale, testCase.scale, 1);
+        auto parentSnapshot = TestUtils::makeSnapshot(snapshotMatrix, Rect(200, 200));
+
+        ResolvedRenderState state(*parentSnapshot, recordedOp, true);
+        testCase.validator(state);
+    }
+}
+
+TEST(BakedOpState, tryConstruct) {
     LinearAllocator allocator;
 
     Matrix4 translate100x0;
@@ -65,41 +154,85 @@
 
     SkPaint paint;
     {
-        RectOp rejectOp(Rect(30, 40, 100, 200), translate100x0, Rect(0, 0, 100, 200), &paint);
-        auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(0, 0, 100, 200));
-        BakedOpState* bakedOp = BakedOpState::tryConstruct(allocator, *snapshot, rejectOp);
+        RectOp rejectOp(Rect(30, 40, 100, 200), translate100x0, Rect(100, 200), &paint);
+        auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(100, 200));
+        BakedOpState* bakedState = BakedOpState::tryConstruct(allocator, *snapshot, rejectOp);
 
-        EXPECT_EQ(bakedOp, nullptr); // rejected by clip, so not constructed
-        EXPECT_LE(allocator.usedSize(), 8u); // no significant allocation space used for rejected op
+        EXPECT_EQ(nullptr, bakedState); // rejected by clip, so not constructed
+        EXPECT_GT(8u, allocator.usedSize()); // no significant allocation space used for rejected op
     }
     {
-        RectOp successOp(Rect(30, 40, 100, 200), Matrix4::identity(), Rect(0, 0, 100, 200), &paint);
-        auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(0, 0, 100, 200));
-        BakedOpState* bakedOp = BakedOpState::tryConstruct(allocator, *snapshot, successOp);
+        RectOp successOp(Rect(30, 40, 100, 200), Matrix4::identity(), Rect(100, 200), &paint);
+        auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(100, 200));
+        BakedOpState* bakedState = BakedOpState::tryConstruct(allocator, *snapshot, successOp);
 
-        EXPECT_NE(bakedOp, nullptr); // NOT rejected by clip, so will be constructed
-        EXPECT_GT(allocator.usedSize(), 64u); // relatively large alloc for non-rejected op
+        EXPECT_NE(nullptr, bakedState); // NOT rejected by clip, so will be constructed
+        EXPECT_LE(64u, allocator.usedSize()); // relatively large alloc for non-rejected op
     }
 }
 
-TEST(BakedOpState, oplessConstructAndReject) {
+TEST(BakedOpState, tryShadowOpConstruct) {
     LinearAllocator allocator;
     {
-        auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(0, 0, 0, 0)); // empty
-        BakedOpState* bakedOp = BakedOpState::tryShadowOpConstruct(allocator, *snapshot, (ShadowOp*)0x1234);
+        auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect()); // Note: empty clip
+        BakedOpState* bakedState = BakedOpState::tryShadowOpConstruct(allocator, *snapshot, (ShadowOp*)0x1234);
 
-        EXPECT_EQ(bakedOp, nullptr); // rejected by clip, so not constructed
-        EXPECT_LE(allocator.usedSize(), 8u); // no significant allocation space used for rejected op
+        EXPECT_EQ(nullptr, bakedState); // rejected by clip, so not constructed
+        EXPECT_GT(8u, allocator.usedSize()); // no significant allocation space used for rejected op
     }
     {
-        auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(0, 0, 100, 200));
-        BakedOpState* bakedOp = BakedOpState::tryShadowOpConstruct(allocator, *snapshot, (ShadowOp*)0x1234);
+        auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(100, 200));
+        BakedOpState* bakedState = BakedOpState::tryShadowOpConstruct(allocator, *snapshot, (ShadowOp*)0x1234);
 
-        EXPECT_NE(bakedOp, nullptr); // NOT rejected by clip, so will be constructed
-        EXPECT_GT(allocator.usedSize(), 64u); // relatively large alloc for non-rejected op
-        EXPECT_EQ((ShadowOp*)0x1234, bakedOp->op);
+        ASSERT_NE(nullptr, bakedState); // NOT rejected by clip, so will be constructed
+        EXPECT_LE(64u, allocator.usedSize()); // relatively large alloc for non-rejected op
     }
 }
 
+TEST(BakedOpState, tryStrokeableOpConstruct) {
+    LinearAllocator allocator;
+    {
+        // check regular rejection
+        SkPaint paint;
+        paint.setStyle(SkPaint::kStrokeAndFill_Style);
+        paint.setStrokeWidth(0.0f);
+        RectOp rejectOp(Rect(0, 0, 100, 200), Matrix4::identity(), Rect(100, 200), &paint);
+        auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect()); // Note: empty clip
+        auto bakedState = BakedOpState::tryStrokeableOpConstruct(allocator, *snapshot, rejectOp,
+                BakedOpState::StrokeBehavior::StyleDefined);
+
+        EXPECT_EQ(nullptr, bakedState);
+        EXPECT_GT(8u, allocator.usedSize()); // no significant allocation space used for rejected op
+    }
+    {
+        // check simple unscaled expansion
+        SkPaint paint;
+        paint.setStyle(SkPaint::kStrokeAndFill_Style);
+        paint.setStrokeWidth(10.0f);
+        RectOp rejectOp(Rect(50, 50, 150, 150), Matrix4::identity(), Rect(200, 200), &paint);
+        auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(200, 200));
+        auto bakedState = BakedOpState::tryStrokeableOpConstruct(allocator, *snapshot, rejectOp,
+                BakedOpState::StrokeBehavior::StyleDefined);
+
+        ASSERT_NE(nullptr, bakedState);
+        EXPECT_EQ(Rect(45, 45, 155, 155), bakedState->computedState.clippedBounds);
+        EXPECT_EQ(0, bakedState->computedState.clipSideFlags);
+    }
+    {
+        // check simple unscaled expansion, and fill style with stroke forced
+        SkPaint paint;
+        paint.setStyle(SkPaint::kFill_Style);
+        paint.setStrokeWidth(10.0f);
+        RectOp rejectOp(Rect(50, 50, 150, 150), Matrix4::identity(), Rect(200, 200), &paint);
+        auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(200, 200));
+        auto bakedState = BakedOpState::tryStrokeableOpConstruct(allocator, *snapshot, rejectOp,
+                BakedOpState::StrokeBehavior::Forced);
+
+        ASSERT_NE(nullptr, bakedState);
+        EXPECT_EQ(Rect(45, 45, 155, 155), bakedState->computedState.clippedBounds);
+        EXPECT_EQ(0, bakedState->computedState.clipSideFlags);
+    }
 }
-}
+
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/tests/unit/ClipAreaTests.cpp b/libs/hwui/tests/unit/ClipAreaTests.cpp
index d6192df..c4d305e 100644
--- a/libs/hwui/tests/unit/ClipAreaTests.cpp
+++ b/libs/hwui/tests/unit/ClipAreaTests.cpp
@@ -92,12 +92,10 @@
 
 TEST(ClipArea, paths) {
     ClipArea area(createClipArea());
-    Matrix4 transform;
-    transform.loadIdentity();
     SkPath path;
     SkScalar r = 100;
     path.addCircle(r, r, r);
-    area.clipPathWithTransform(path, &transform, SkRegion::kIntersect_Op);
+    area.clipPathWithTransform(path, &Matrix4::identity(), SkRegion::kIntersect_Op);
     EXPECT_FALSE(area.isEmpty());
     EXPECT_FALSE(area.isSimple());
     EXPECT_FALSE(area.isRectangleList());
@@ -116,11 +114,10 @@
     ClipArea area(createClipArea());
     area.setClip(0, 0, 100, 100);
 
-    Matrix4 transform;
-    transform.loadIdentity();
     Rect expected(-50, -50, 50, 50);
-    area.clipRectWithTransform(expected, &transform, SkRegion::kReplace_Op);
+    area.clipRectWithTransform(expected, &Matrix4::identity(), SkRegion::kReplace_Op);
     EXPECT_EQ(expected, area.getClipRect());
 }
+
 }
 }
diff --git a/libs/hwui/tests/unit/DamageAccumulatorTests.cpp b/libs/hwui/tests/unit/DamageAccumulatorTests.cpp
index 29354a7..7700138 100644
--- a/libs/hwui/tests/unit/DamageAccumulatorTests.cpp
+++ b/libs/hwui/tests/unit/DamageAccumulatorTests.cpp
@@ -31,13 +31,11 @@
 // as the output.
 TEST(DamageAccumulator, identity) {
     DamageAccumulator da;
-    Matrix4 identity;
     SkRect curDirty;
-    identity.loadIdentity();
-    da.pushTransform(&identity);
+    da.pushTransform(&Matrix4::identity());
     da.dirty(50, 50, 100, 100);
     {
-        da.pushTransform(&identity);
+        da.pushTransform(&Matrix4::identity());
         da.peekAtDirty(&curDirty);
         ASSERT_EQ(SkRect(), curDirty);
         da.popTransform();
@@ -68,15 +66,13 @@
 // Test that dirty rectangles are being unioned across "siblings
 TEST(DamageAccumulator, union) {
     DamageAccumulator da;
-    Matrix4 identity;
     SkRect curDirty;
-    identity.loadIdentity();
-    da.pushTransform(&identity);
+    da.pushTransform(&Matrix4::identity());
     {
-        da.pushTransform(&identity);
+        da.pushTransform(&Matrix4::identity());
         da.dirty(50, 50, 100, 100);
         da.popTransform();
-        da.pushTransform(&identity);
+        da.pushTransform(&Matrix4::identity());
         da.dirty(150, 50, 200, 125);
         da.popTransform();
     }
diff --git a/libs/hwui/tests/unit/OpReordererTests.cpp b/libs/hwui/tests/unit/OpReordererTests.cpp
index 98a430a..5eac498 100644
--- a/libs/hwui/tests/unit/OpReordererTests.cpp
+++ b/libs/hwui/tests/unit/OpReordererTests.cpp
@@ -65,12 +65,22 @@
     virtual void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) {}
     virtual void endFrame() {}
 
-    // define virtual defaults for direct
-#define BASE_OP_METHOD(Type) \
+    // define virtual defaults for single draw methods
+#define X(Type) \
     virtual void on##Type(const Type&, const BakedOpState&) { \
         ADD_FAILURE() << #Type " not expected in this test"; \
     }
-    MAP_OPS(BASE_OP_METHOD)
+    MAP_OPS(X)
+#undef X
+
+    // define virtual defaults for merged draw methods
+#define X(Type) \
+    virtual void onMerged##Type##s(const MergedBakedOpList& opList) { \
+        ADD_FAILURE() << "Merged " #Type "s not expected in this test"; \
+    }
+    MAP_MERGED_OPS(X)
+#undef X
+
     int getIndex() { return mIndex; }
 
 protected:
@@ -83,11 +93,21 @@
  */
 class TestDispatcher {
 public:
-#define DISPATCHER_METHOD(Type) \
+    // define single op methods, which redirect to TestRendererBase
+#define X(Type) \
     static void on##Type(TestRendererBase& renderer, const Type& op, const BakedOpState& state) { \
         renderer.on##Type(op, state); \
     }
-    MAP_OPS(DISPATCHER_METHOD);
+    MAP_OPS(X);
+#undef X
+
+    // define merged op methods, which redirect to TestRendererBase
+#define X(Type) \
+    static void onMerged##Type##s(TestRendererBase& renderer, const MergedBakedOpList& opList) { \
+        renderer.onMerged##Type##s(opList); \
+    }
+    MAP_MERGED_OPS(X);
+#undef X
 };
 
 class FailRenderer : public TestRendererBase {};
@@ -124,6 +144,32 @@
     EXPECT_EQ(4, renderer.getIndex()); // 2 ops + start + end
 }
 
+TEST(OpReorderer, simpleStroke) {
+    class SimpleStrokeTestRenderer : public TestRendererBase {
+    public:
+        void onPointsOp(const PointsOp& op, const BakedOpState& state) override {
+            EXPECT_EQ(0, mIndex++);
+            // even though initial bounds are empty...
+            EXPECT_TRUE(op.unmappedBounds.isEmpty())
+                    << "initial bounds should be empty, since they're unstroked";
+            EXPECT_EQ(Rect(45, 45, 55, 55), state.computedState.clippedBounds)
+                    << "final bounds should account for stroke";
+        }
+    };
+
+    auto node = TestUtils::createNode(0, 0, 100, 200,
+            [](RenderProperties& props, RecordingCanvas& canvas) {
+        SkPaint strokedPaint;
+        strokedPaint.setStrokeWidth(10);
+        canvas.drawPoint(50, 50, strokedPaint);
+    });
+    OpReorderer reorderer(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 200), 100, 200,
+            createSyncedNodeList(node), sLightCenter);
+    SimpleStrokeTestRenderer renderer;
+    reorderer.replayBakedOps<TestDispatcher>(renderer);
+    EXPECT_EQ(1, renderer.getIndex());
+}
+
 TEST(OpReorderer, simpleRejection) {
     auto node = TestUtils::createNode(0, 0, 200, 200,
             [](RenderProperties& props, RecordingCanvas& canvas) {
@@ -153,7 +199,8 @@
 
     auto node = TestUtils::createNode(0, 0, 200, 200,
             [](RenderProperties& props, RecordingCanvas& canvas) {
-        SkBitmap bitmap = TestUtils::createSkBitmap(10, 10);
+        SkBitmap bitmap = TestUtils::createSkBitmap(10, 10,
+                kAlpha_8_SkColorType); // Disable merging by using alpha 8 bitmap
 
         // Alternate between drawing rects and bitmaps, with bitmaps overlapping rects.
         // Rects don't overlap bitmaps, so bitmaps should be brought to front as a group.
@@ -171,7 +218,7 @@
     SimpleBatchingTestRenderer renderer;
     reorderer.replayBakedOps<TestDispatcher>(renderer);
     EXPECT_EQ(2 * LOOPS, renderer.getIndex())
-            << "Expect number of ops = 2 * loop count"; // TODO: force no merging
+            << "Expect number of ops = 2 * loop count";
 }
 
 TEST(OpReorderer, textStrikethroughBatching) {
@@ -181,8 +228,10 @@
         void onRectOp(const RectOp& op, const BakedOpState& state) override {
             EXPECT_TRUE(mIndex++ >= LOOPS) << "Strikethrough rects should be above all text";
         }
-        void onTextOp(const TextOp& op, const BakedOpState& state) override {
-            EXPECT_TRUE(mIndex++ < LOOPS) << "Text should be beneath all strikethrough rects";
+        void onMergedTextOps(const MergedBakedOpList& opList) override {
+            EXPECT_EQ(0, mIndex);
+            mIndex += opList.count;
+            EXPECT_EQ(5u, opList.count);
         }
     };
     auto node = TestUtils::createNode(0, 0, 200, 2000,
diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
index 2449ce8..ba9d185 100644
--- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp
+++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
@@ -44,7 +44,7 @@
 TEST(RecordingCanvas, drawLines) {
     auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) {
         SkPaint paint;
-        paint.setStrokeWidth(20);
+        paint.setStrokeWidth(20); // doesn't affect recorded bounds - would be resolved at bake time
         float points[] = { 0, 0, 20, 10, 30, 40, 90 }; // NB: only 1 valid line
         canvas.drawLines(&points[0], 7, paint);
     });
@@ -54,8 +54,8 @@
     ASSERT_EQ(RecordedOpId::LinesOp, op->opId);
     EXPECT_EQ(4, ((LinesOp*)op)->floatCount)
             << "float count must be rounded down to closest multiple of 4";
-    EXPECT_EQ(Rect(-10, -10, 30, 20), op->unmappedBounds)
-            << "unmapped bounds must be size of line, outset by 1/2 stroke width";
+    EXPECT_EQ(Rect(0, 0, 20, 10), op->unmappedBounds)
+            << "unmapped bounds must be size of line, and not outset for stroke width";
 }
 
 TEST(RecordingCanvas, drawRect) {
diff --git a/libs/hwui/utils/RingBuffer.h b/libs/hwui/utils/RingBuffer.h
index 6895f07..06bcdcd 100644
--- a/libs/hwui/utils/RingBuffer.h
+++ b/libs/hwui/utils/RingBuffer.h
@@ -32,7 +32,7 @@
     ~RingBuffer() {}
 
     constexpr size_t capacity() const { return SIZE; }
-    size_t size() { return mCount; }
+    size_t size() const { return mCount; }
 
     T& next() {
         mHead = (mHead + 1) % SIZE;
@@ -54,6 +54,10 @@
         return mBuffer[(mHead + index + 1) % mCount];
     }
 
+    const T& operator[](size_t index) const {
+        return mBuffer[(mHead + index + 1) % mCount];
+    }
+
     void clear() {
         mCount = 0;
         mHead = -1;
diff --git a/libs/hwui/utils/TestWindowContext.cpp b/libs/hwui/utils/TestWindowContext.cpp
index 84aae75..05b4a72 100644
--- a/libs/hwui/utils/TestWindowContext.cpp
+++ b/libs/hwui/utils/TestWindowContext.cpp
@@ -180,6 +180,10 @@
 TestWindowContext::TestWindowContext() :
     mData (nullptr) { }
 
+TestWindowContext::~TestWindowContext() {
+    delete mData;
+}
+
 void TestWindowContext::initialize(int width, int height)  {
     mData = new TestWindowData(SkISize::Make(width, height));
 }
diff --git a/libs/hwui/utils/TestWindowContext.h b/libs/hwui/utils/TestWindowContext.h
index 445a11b..48ec952 100644
--- a/libs/hwui/utils/TestWindowContext.h
+++ b/libs/hwui/utils/TestWindowContext.h
@@ -35,6 +35,7 @@
 public:
 
     TestWindowContext();
+    ~TestWindowContext();
 
     /// We need to know the size of the window.
     void initialize(int width, int height);
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
index 045216b..3e75759 100644
--- a/media/java/android/media/Image.java
+++ b/media/java/android/media/Image.java
@@ -141,6 +141,16 @@
      *     {@link android.hardware.camera2.CameraDevice CameraDevice}.
      *   </td>
      * </tr>
+     * <tr>
+     *   <td>{@link android.graphics.ImageFormat#RAW_PRIVATE RAW_PRIVATE}</td>
+     *   <td>1</td>
+     *   <td>A single plane of raw sensor image data of private layout.
+     *   The details of the layout is implementation specific. Row stride and
+     *   pixel stride are undefined for this format. Calling {@link Plane#getRowStride()}
+     *   or {@link Plane#getPixelStride()} on RAW_PRIVATE image will cause
+     *   UnSupportedOperationException being thrown.
+     *   </td>
+     * </tr>
      * </table>
      *
      * @see android.graphics.ImageFormat
@@ -341,7 +351,13 @@
          * <p>The row stride for this color plane, in bytes.</p>
          *
          * <p>This is the distance between the start of two consecutive rows of
-         * pixels in the image. The row stride is always greater than 0.</p>
+         * pixels in the image. Note that row stried is undefined for some formats
+         * such as
+         * {@link android.graphics.ImageFormat#RAW_PRIVATE RAW_PRIVATE},
+         * and calling getRowStride on images of these formats will
+         * cause an UnsupportedOperationException being thrown.
+         * For formats where row stride is well defined, the row stride
+         * is always greater than 0.</p>
          */
         public abstract int getRowStride();
         /**
@@ -350,7 +366,12 @@
          * <p>This is the distance between two consecutive pixel values in a row
          * of pixels. It may be larger than the size of a single pixel to
          * account for interleaved image data or padded formats.
-         * The pixel stride is always greater than 0.</p>
+         * Note that pixel stride is undefined for some formats such as
+         * {@link android.graphics.ImageFormat#RAW_PRIVATE RAW_PRIVATE},
+         * and calling getPixelStride on images of these formats will
+         * cause an UnsupportedOperationException being thrown.
+         * For formats where pixel stride is well defined, the pixel stride
+         * is always greater than 0.</p>
          */
         public abstract int getPixelStride();
         /**
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index 2164eec..397ab15 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -17,10 +17,10 @@
 package android.media;
 
 import android.graphics.ImageFormat;
-import android.graphics.PixelFormat;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.util.Log;
 import android.view.Surface;
 
 import dalvik.system.VMRuntime;
@@ -29,6 +29,8 @@
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.NioUtils;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
@@ -145,7 +147,7 @@
                     "NV21 format is not supported");
         }
 
-        mNumPlanes = getNumPlanesFromFormat();
+        mNumPlanes = ImageUtils.getNumPlanesForFormat(mFormat);
 
         nativeInit(new WeakReference<ImageReader>(this), width, height, format, maxImages);
 
@@ -323,21 +325,27 @@
      * @see #ACQUIRE_SUCCESS
      */
     private int acquireNextSurfaceImage(SurfaceImage si) {
+        synchronized (mCloseLock) {
+            int status = nativeImageSetup(si);
 
-        int status = nativeImageSetup(si);
+            switch (status) {
+                case ACQUIRE_SUCCESS:
+                    si.createSurfacePlanes();
+                    si.mIsImageValid = true;
+                case ACQUIRE_NO_BUFS:
+                case ACQUIRE_MAX_IMAGES:
+                    break;
+                default:
+                    throw new AssertionError("Unknown nativeImageSetup return code " + status);
+            }
 
-        switch (status) {
-            case ACQUIRE_SUCCESS:
-                si.createSurfacePlanes();
-                si.mIsImageValid = true;
-            case ACQUIRE_NO_BUFS:
-            case ACQUIRE_MAX_IMAGES:
-                break;
-            default:
-                throw new AssertionError("Unknown nativeImageSetup return code " + status);
+            // Only keep track the successfully acquired image, as the native buffer is only mapped
+            // for such case.
+            if (status == ACQUIRE_SUCCESS) {
+                mAcquiredImages.add(si);
+            }
+            return status;
         }
-
-        return status;
     }
 
     /**
@@ -398,7 +406,11 @@
                 "This image was not produced by an ImageReader");
         }
         SurfaceImage si = (SurfaceImage) i;
-        if (si.getReader() != this) {
+        if (si.mIsImageValid == false) {
+            return;
+        }
+
+        if (si.getReader() != this || !mAcquiredImages.contains(i)) {
             throw new IllegalArgumentException(
                 "This image was not produced by this ImageReader");
         }
@@ -406,6 +418,7 @@
         si.clearSurfacePlanes();
         nativeReleaseImage(i);
         si.mIsImageValid = false;
+        mAcquiredImages.remove(i);
     }
 
     /**
@@ -475,7 +488,24 @@
     public void close() {
         setOnImageAvailableListener(null, null);
         if (mSurface != null) mSurface.release();
-        nativeClose();
+
+        /**
+         * Close all outstanding acquired images before closing the ImageReader. It is a good
+         * practice to close all the images as soon as it is not used to reduce system instantaneous
+         * memory pressure. CopyOnWrite list will use a copy of current list content. For the images
+         * being closed by other thread (e.g., GC thread), doubling the close call is harmless. For
+         * the image being acquired by other threads, mCloseLock is used to synchronize close and
+         * acquire operations.
+         */
+        synchronized (mCloseLock) {
+            for (Image image : mAcquiredImages) {
+                image.close();
+            }
+            mAcquiredImages.clear();
+
+            nativeClose();
+        }
+
         if (mEstimatedNativeAllocBytes > 0) {
             VMRuntime.getRuntime().registerNativeFree(mEstimatedNativeAllocBytes);
             mEstimatedNativeAllocBytes = 0;
@@ -540,45 +570,6 @@
 
         nativeDetachImage(image);
         si.setDetached(true);
-   }
-
-    /**
-     * Only a subset of the formats defined in
-     * {@link android.graphics.ImageFormat ImageFormat} and
-     * {@link android.graphics.PixelFormat PixelFormat} are supported by
-     * ImageReader. When reading RGB data from a surface, the formats defined in
-     * {@link android.graphics.PixelFormat PixelFormat} can be used, when
-     * reading YUV, JPEG or raw sensor data (for example, from camera or video
-     * decoder), formats from {@link android.graphics.ImageFormat ImageFormat}
-     * are used.
-     */
-    private int getNumPlanesFromFormat() {
-        switch (mFormat) {
-            case ImageFormat.YV12:
-            case ImageFormat.YUV_420_888:
-            case ImageFormat.NV21:
-                return 3;
-            case ImageFormat.NV16:
-                return 2;
-            case PixelFormat.RGB_565:
-            case PixelFormat.RGBA_8888:
-            case PixelFormat.RGBX_8888:
-            case PixelFormat.RGB_888:
-            case ImageFormat.JPEG:
-            case ImageFormat.YUY2:
-            case ImageFormat.Y8:
-            case ImageFormat.Y16:
-            case ImageFormat.RAW_SENSOR:
-            case ImageFormat.RAW10:
-            case ImageFormat.DEPTH16:
-            case ImageFormat.DEPTH_POINT_CLOUD:
-                return 1;
-            case ImageFormat.PRIVATE:
-                return 0;
-            default:
-                throw new UnsupportedOperationException(
-                        String.format("Invalid format specified %d", mFormat));
-        }
     }
 
     private boolean isImageOwnedbyMe(Image image) {
@@ -612,7 +603,6 @@
         }
     }
 
-
     private final int mWidth;
     private final int mHeight;
     private final int mFormat;
@@ -622,8 +612,12 @@
     private int mEstimatedNativeAllocBytes;
 
     private final Object mListenerLock = new Object();
+    private final Object mCloseLock = new Object();
     private OnImageAvailableListener mListener;
     private ListenerHandler mListenerHandler;
+    // Keep track of the successfully acquired Images. This need to be thread safe as the images
+    // could be closed by different threads (e.g., application thread and GC thread).
+    private List<Image> mAcquiredImages = new CopyOnWriteArrayList<Image>();
 
     /**
      * This field is used by native code, do not access or modify.
@@ -657,9 +651,7 @@
 
         @Override
         public void close() {
-            if (mIsImageValid) {
-                ImageReader.this.releaseImage(this);
-            }
+            ImageReader.this.releaseImage(this);
         }
 
         public ImageReader getReader() {
@@ -683,6 +675,7 @@
             switch(getFormat()) {
                 case ImageFormat.JPEG:
                 case ImageFormat.DEPTH_POINT_CLOUD:
+                case ImageFormat.RAW_PRIVATE:
                     width = ImageReader.this.getWidth();
                     break;
                 default:
@@ -698,6 +691,7 @@
             switch(getFormat()) {
                 case ImageFormat.JPEG:
                 case ImageFormat.DEPTH_POINT_CLOUD:
+                case ImageFormat.RAW_PRIVATE:
                     height = ImageReader.this.getHeight();
                     break;
                 default:
@@ -799,12 +793,20 @@
             @Override
             public int getPixelStride() {
                 SurfaceImage.this.throwISEIfImageIsInvalid();
+                if (ImageReader.this.mFormat == ImageFormat.RAW_PRIVATE) {
+                    throw new UnsupportedOperationException(
+                            "getPixelStride is not supported for RAW_PRIVATE plane");
+                }
                 return mPixelStride;
             }
 
             @Override
             public int getRowStride() {
                 SurfaceImage.this.throwISEIfImageIsInvalid();
+                if (ImageReader.this.mFormat == ImageFormat.RAW_PRIVATE) {
+                    throw new UnsupportedOperationException(
+                            "getRowStride is not supported for RAW_PRIVATE plane");
+                }
                 return mRowStride;
             }
 
diff --git a/media/java/android/media/ImageUtils.java b/media/java/android/media/ImageUtils.java
index ba3949a..abf6b20 100644
--- a/media/java/android/media/ImageUtils.java
+++ b/media/java/android/media/ImageUtils.java
@@ -57,7 +57,11 @@
             case ImageFormat.Y8:
             case ImageFormat.Y16:
             case ImageFormat.RAW_SENSOR:
+            case ImageFormat.RAW_PRIVATE:
             case ImageFormat.RAW10:
+            case ImageFormat.RAW12:
+            case ImageFormat.DEPTH16:
+            case ImageFormat.DEPTH_POINT_CLOUD:
                 return 1;
             case ImageFormat.PRIVATE:
                 return 0;
@@ -95,6 +99,10 @@
                 dst.getFormat() == ImageFormat.PRIVATE) {
             throw new IllegalArgumentException("PRIVATE format images are not copyable");
         }
+        if (src.getFormat() == ImageFormat.RAW_PRIVATE) {
+            throw new IllegalArgumentException(
+                    "Copy of RAW_OPAQUE format has not been implemented");
+        }
         if (!(dst.getOwner() instanceof ImageWriter)) {
             throw new IllegalArgumentException("Destination image is not from ImageWriter. Only"
                     + " the images from ImageWriter are writable");
@@ -190,7 +198,8 @@
             case ImageFormat.YV12:
             case ImageFormat.YUV_420_888:
             case ImageFormat.NV21:
-            case ImageFormat.PRIVATE: // A really rough estimate because the real size is unknown.
+            case ImageFormat.RAW12:
+            case ImageFormat.PRIVATE: // A rough estimate because the real size is unknown.
                 estimatedBytePerPixel = 1.5;
                 break;
             case ImageFormat.NV16:
@@ -198,6 +207,7 @@
             case ImageFormat.YUY2:
             case ImageFormat.Y16:
             case ImageFormat.RAW_SENSOR:
+            case ImageFormat.RAW_PRIVATE: // round estimate, real size is unknown
             case ImageFormat.DEPTH16:
                 estimatedBytePerPixel = 2.0;
                 break;
@@ -242,6 +252,7 @@
             case ImageFormat.Y16:
             case ImageFormat.RAW_SENSOR:
             case ImageFormat.RAW10:
+            case ImageFormat.RAW12:
                 return new Size(image.getWidth(), image.getHeight());
             case ImageFormat.PRIVATE:
                 return new Size(0, 0);
diff --git a/media/java/android/media/ImageWriter.java b/media/java/android/media/ImageWriter.java
index 9fb3286..851d436 100644
--- a/media/java/android/media/ImageWriter.java
+++ b/media/java/android/media/ImageWriter.java
@@ -18,17 +18,21 @@
 
 import android.graphics.ImageFormat;
 import android.graphics.Rect;
+import android.hardware.camera2.utils.SurfaceUtils;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.util.Size;
 import android.view.Surface;
 
+import dalvik.system.VMRuntime;
+
 import java.lang.ref.WeakReference;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.NioUtils;
-import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
  * <p>
@@ -83,8 +87,10 @@
     private int mWriterFormat;
 
     private final int mMaxImages;
-    // Keep track of the currently dequeued Image.
-    private List<Image> mDequeuedImages = new ArrayList<Image>();
+    // Keep track of the currently dequeued Image. This need to be thread safe as the images
+    // could be closed by different threads (e.g., application thread and GC thread).
+    private List<Image> mDequeuedImages = new CopyOnWriteArrayList<Image>();
+    private int mEstimatedNativeAllocBytes;
 
     /**
      * <p>
@@ -128,6 +134,16 @@
         // Note that the underlying BufferQueue is working in synchronous mode
         // to avoid dropping any buffers.
         mNativeContext = nativeInit(new WeakReference<ImageWriter>(this), surface, maxImages);
+
+        // Estimate the native buffer allocation size and register it so it gets accounted for
+        // during GC. Note that this doesn't include the buffers required by the buffer queue
+        // itself and the buffers requested by the producer.
+        Size surfSize = SurfaceUtils.getSurfaceSize(surface);
+        int format = SurfaceUtils.getSurfaceFormat(surface);
+        mEstimatedNativeAllocBytes =
+                ImageUtils.getEstimatedNativeAllocBytes(surfSize.getWidth(),surfSize.getHeight(),
+                        format, maxImages);
+        VMRuntime.getRuntime().registerNativeAllocation(mEstimatedNativeAllocBytes);
     }
 
     /**
@@ -432,6 +448,11 @@
         mDequeuedImages.clear();
         nativeClose(mNativeContext);
         mNativeContext = 0;
+
+        if (mEstimatedNativeAllocBytes > 0) {
+            VMRuntime.getRuntime().registerNativeFree(mEstimatedNativeAllocBytes);
+            mEstimatedNativeAllocBytes = 0;
+        }
     }
 
     @Override
@@ -569,9 +590,8 @@
         }
 
         WriterSurfaceImage wi = (WriterSurfaceImage) image;
-
         if (!wi.mIsImageValid) {
-            throw new IllegalStateException("Image is invalid");
+            return;
         }
 
         /**
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 4101935..e6bc8f1 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -1735,7 +1735,8 @@
             CodecProfileLevel[] profileLevels = mParent.profileLevels;
             String mime = mParent.getMimeType();
 
-            if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_AVC)) {
+            if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_AVC) ||
+                    mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_DOLBY_AVC)) {
                 maxBlocks = 99;
                 maxBlocksPerSecond = 1485;
                 maxBps = 64000;
@@ -2089,7 +2090,8 @@
                 applyMacroBlockLimits(Short.MAX_VALUE, Short.MAX_VALUE,
                         maxBlocks, maxBlocksPerSecond, blockSize, blockSize,
                         1 /* widthAlignment */, 1 /* heightAlignment */);
-            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)) {
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC) ||
+                    mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_DOLBY_HEVC)) {
                 maxBlocks = 36864;
                 maxBlocksPerSecond = maxBlocks * 15;
                 maxBps = 128000;
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index ab61e2b..db0c5bb 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -906,18 +906,6 @@
             throws DeniedByServerException;
 
     /**
-     * Remove provisioning from a device.  Only system apps may unprovision a
-     * device.  Note that removing provisioning will invalidate any keys saved
-     * for offline use (KEY_TYPE_OFFLINE), which may render downloaded content
-     * unplayable until new licenses are acquired.  Since provisioning is global
-     * to the device, license invalidation will apply to all content downloaded
-     * by any app, so appropriate warnings should be given to the user.
-     * @hide
-     */
-    @SystemApi
-    public native void unprovisionDevice();
-
-    /**
      * A means of enforcing limits on the number of concurrent streams per subscriber
      * across devices is provided via SecureStop. This is achieved by securely
      * monitoring the lifetime of sessions.
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index b2fa0ac..a102e51 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -92,6 +92,8 @@
     public static final String MIMETYPE_VIDEO_H263 = "video/3gpp";
     public static final String MIMETYPE_VIDEO_MPEG2 = "video/mpeg2";
     public static final String MIMETYPE_VIDEO_RAW = "video/raw";
+    public static final String MIMETYPE_VIDEO_DOLBY_AVC = "video/dolby-avc";
+    public static final String MIMETYPE_VIDEO_DOLBY_HEVC = "video/dolby-hevc";
 
     public static final String MIMETYPE_AUDIO_AMR_NB = "audio/3gpp";
     public static final String MIMETYPE_AUDIO_AMR_WB = "audio/amr-wb";
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index a046512..bcc2b406 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -18,6 +18,7 @@
 
 import android.Manifest;
 import android.annotation.DrawableRes;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.app.ActivityThread;
 import android.content.BroadcastReceiver;
@@ -41,6 +42,8 @@
 import android.util.Log;
 import android.view.Display;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -201,6 +204,7 @@
                         info.mDescription = sStatic.mResources.getText(
                                 com.android.internal.R.string.bluetooth_a2dp_audio_route_name);
                         info.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO;
+                        info.mDeviceType = RouteInfo.DEVICE_TYPE_BLUETOOTH;
                         sStatic.mBluetoothA2dpRoute = info;
                         addRouteStatic(sStatic.mBluetoothA2dpRoute);
                     } else {
@@ -480,6 +484,7 @@
             route.mName = globalRoute.name;
             route.mDescription = globalRoute.description;
             route.mSupportedTypes = globalRoute.supportedTypes;
+            route.mDeviceType = globalRoute.deviceType;
             route.mEnabled = globalRoute.enabled;
             route.setRealStatusCode(globalRoute.statusCode);
             route.mPlaybackType = globalRoute.playbackType;
@@ -1411,6 +1416,7 @@
         newRoute.mDescription = sStatic.mResources.getText(
                 com.android.internal.R.string.wireless_display_route_description);
         newRoute.updatePresentationDisplay();
+        newRoute.mDeviceType = RouteInfo.DEVICE_TYPE_TV;
         return newRoute;
     }
 
@@ -1470,6 +1476,7 @@
         CharSequence mDescription;
         private CharSequence mStatus;
         int mSupportedTypes;
+        int mDeviceType;
         RouteGroup mGroup;
         final RouteCategory mCategory;
         Drawable mIcon;
@@ -1502,6 +1509,42 @@
         /** @hide */ public static final int STATUS_IN_USE = 5;
         /** @hide */ public static final int STATUS_CONNECTED = 6;
 
+        /** @hide */
+        @IntDef({DEVICE_TYPE_UNKNOWN, DEVICE_TYPE_TV, DEVICE_TYPE_SPEAKER, DEVICE_TYPE_BLUETOOTH})
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface DeviceType {}
+
+        /**
+         * The default receiver device type of the route indicating the type is unknown.
+         *
+         * @see #getDeviceType
+         */
+        public static final int DEVICE_TYPE_UNKNOWN = 0;
+
+        /**
+         * A receiver device type of the route indicating the presentation of the media is happening
+         * on a TV.
+         *
+         * @see #getDeviceType
+         */
+        public static final int DEVICE_TYPE_TV = 1;
+
+        /**
+         * A receiver device type of the route indicating the presentation of the media is happening
+         * on a speaker.
+         *
+         * @see #getDeviceType
+         */
+        public static final int DEVICE_TYPE_SPEAKER = 2;
+
+        /**
+         * A receiver device type of the route indicating the presentation of the media is happening
+         * on a bluetooth device such as a bluetooth speaker.
+         *
+         * @see #getDeviceType
+         */
+        public static final int DEVICE_TYPE_BLUETOOTH = 3;
+
         private Object mTag;
 
         /**
@@ -1533,6 +1576,7 @@
 
         RouteInfo(RouteCategory category) {
             mCategory = category;
+            mDeviceType = DEVICE_TYPE_UNKNOWN;
         }
 
         /**
@@ -1670,6 +1714,18 @@
             return mSupportedTypes;
         }
 
+        /**
+         * Gets the type of the receiver device associated with this route.
+         *
+         * @return The type of the receiver device associated with this route:
+         * {@link #DEVICE_TYPE_BLUETOOTH}, {@link #DEVICE_TYPE_TV}, {@link #DEVICE_TYPE_SPEAKER},
+         * or {@link #DEVICE_TYPE_UNKNOWN}.
+         */
+        @DeviceType
+        public int getDeviceType() {
+            return mDeviceType;
+        }
+
         /** @hide */
         public boolean matchesTypes(int types) {
             return (mSupportedTypes & types) != 0;
diff --git a/media/java/android/media/MediaRouterClientState.java b/media/java/android/media/MediaRouterClientState.java
index 54b8276..34e18f6 100644
--- a/media/java/android/media/MediaRouterClientState.java
+++ b/media/java/android/media/MediaRouterClientState.java
@@ -104,6 +104,7 @@
         public int volumeMax;
         public int volumeHandling;
         public int presentationDisplayId;
+        public @MediaRouter.RouteInfo.DeviceType int deviceType;
 
         public RouteInfo(String id) {
             this.id = id;
@@ -113,6 +114,7 @@
             playbackStream = -1;
             volumeHandling = MediaRouter.RouteInfo.PLAYBACK_VOLUME_FIXED;
             presentationDisplayId = -1;
+            deviceType = MediaRouter.RouteInfo.DEVICE_TYPE_UNKNOWN;
         }
 
         public RouteInfo(RouteInfo other) {
@@ -128,6 +130,7 @@
             volumeMax = other.volumeMax;
             volumeHandling = other.volumeHandling;
             presentationDisplayId = other.presentationDisplayId;
+            deviceType = other.deviceType;
         }
 
         RouteInfo(Parcel in) {
@@ -143,6 +146,7 @@
             volumeMax = in.readInt();
             volumeHandling = in.readInt();
             presentationDisplayId = in.readInt();
+            deviceType = in.readInt();
         }
 
         @Override
@@ -164,6 +168,7 @@
             dest.writeInt(volumeMax);
             dest.writeInt(volumeHandling);
             dest.writeInt(presentationDisplayId);
+            dest.writeInt(deviceType);
         }
 
         @Override
@@ -180,6 +185,7 @@
                     + ", volumeMax=" + volumeMax
                     + ", volumeHandling=" + volumeHandling
                     + ", presentationDisplayId=" + presentationDisplayId
+                    + ", deviceType=" + deviceType
                     + " }";
         }
 
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index 3ffdb17..1c043e0 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -101,6 +101,8 @@
     void setOpaqueConsumer(const sp<BufferItemConsumer>& consumer) { mOpaqueConsumer = consumer; }
     BufferItemConsumer* getOpaqueConsumer() { return mOpaqueConsumer.get(); }
     // This is the only opaque format exposed in the ImageFormat public API.
+    // Note that we do support CPU access for HAL_PIXEL_FORMAT_RAW_OPAQUE
+    // (ImageFormat#RAW_PRIVATE) so it doesn't count as opaque here.
     bool isOpaque() { return mFormat == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; }
 
     void setProducer(const sp<IGraphicBufferProducer>& producer) { mProducer = producer; }
@@ -470,7 +472,8 @@
         case HAL_PIXEL_FORMAT_BLOB:
             // Used for JPEG data, height must be 1, width == size, single plane.
             ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
-            ALOG_ASSERT(buffer->height == 1, "JPEG should has height value %d", buffer->height);
+            ALOG_ASSERT(buffer->height == 1,
+                    "JPEG should has height value one but got %d", buffer->height);
 
             pData = buffer->data;
             dataSize = Image_getJpegSize(buffer, usingRGBAOverride);
@@ -482,6 +485,14 @@
             pData = buffer->data;
             dataSize = buffer->stride * buffer->height * bytesPerPixel;
             break;
+        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
+            // Used for RAW_OPAQUE data, height must be 1, width == size, single plane.
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            ALOG_ASSERT(buffer->height == 1,
+                    "RAW_PRIVATE should has height value one but got %d", buffer->height);
+            pData = buffer->data;
+            dataSize = buffer->width;
+            break;
         case HAL_PIXEL_FORMAT_RAW10:
             // Single plane 10bpp bayer data.
             ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
@@ -593,6 +604,10 @@
             ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
             pixelStride = 3;
             break;
+        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            pixelStride = 0; // RAW OPAQUE doesn't have pixel stride
+            break;
         default:
             jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException",
                                  "Pixel format: 0x%x is unsupported", fmt);
@@ -669,6 +684,10 @@
             ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
             rowStride = buffer->stride * 3;
             break;
+        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            rowStride = 0; // RAW OPAQUE doesn't have row stride
+            break;
         default:
             ALOGE("%s Pixel format: 0x%x is unsupported", __FUNCTION__, fmt);
             jniThrowException(env, "java/lang/UnsupportedOperationException",
@@ -933,7 +952,7 @@
         CpuConsumer* consumer = ctx->getCpuConsumer();
         CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, image);
         if (!buffer) {
-            ALOGW("Image already released!!!");
+            // Release an already closed image is harmless.
             return;
         }
         consumer->unlockBuffer(*buffer);
@@ -1078,7 +1097,8 @@
     ALOGV("%s:", __FUNCTION__);
     JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz);
     if (ctx == NULL) {
-        jniThrowRuntimeException(env, "ImageReaderContext is not initialized");
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "ImageReader is not initialized or was already closed");
         return -1;
     }
 
diff --git a/media/jni/android_media_ImageWriter.cpp b/media/jni/android_media_ImageWriter.cpp
index f92a8ef..f50da85 100644
--- a/media/jni/android_media_ImageWriter.cpp
+++ b/media/jni/android_media_ImageWriter.cpp
@@ -403,8 +403,7 @@
     ALOGV("%s", __FUNCTION__);
     JNIImageWriterContext* const ctx = reinterpret_cast<JNIImageWriterContext *>(nativeCtx);
     if (ctx == NULL || thiz == NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException",
-                "ImageWriterContext is not initialized");
+        ALOGW("ImageWriter#close called before Image#close, consider calling Image#close first");
         return;
     }
 
@@ -414,8 +413,7 @@
     int fenceFd = -1;
     Image_getNativeContext(env, image, &buffer, &fenceFd);
     if (buffer == NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException",
-                "Image is not initialized");
+        // Cancel an already cancelled image is harmless.
         return;
     }
 
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index 275de1ad..b8849c6 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -1048,22 +1048,6 @@
     return certificateObj;
 }
 
-static void android_media_MediaDrm_unprovisionDeviceNative(
-    JNIEnv *env, jobject thiz) {
-    sp<IDrm> drm = GetDrm(env, thiz);
-
-    if (drm == NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException",
-                          "MediaDrm obj is null");
-        return;
-    }
-
-    status_t err = drm->unprovisionDevice();
-
-    throwExceptionAsNecessary(env, err, "Failed to handle provision response");
-    return;
-}
-
 static jobject android_media_MediaDrm_getSecureStops(
     JNIEnv *env, jobject thiz) {
     sp<IDrm> drm = GetDrm(env, thiz);
@@ -1496,9 +1480,6 @@
     { "provideProvisionResponseNative", "([B)Landroid/media/MediaDrm$Certificate;",
       (void *)android_media_MediaDrm_provideProvisionResponseNative },
 
-    { "unprovisionDevice", "()V",
-      (void *)android_media_MediaDrm_unprovisionDeviceNative },
-
     { "getSecureStops", "()Ljava/util/List;",
       (void *)android_media_MediaDrm_getSecureStops },
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
index 57969ba..6f74203 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
@@ -129,7 +129,7 @@
 
             int res = mUtils.getCameraService().supportsCameraApi(cameraId, API_VERSION_2);
 
-            if (res != CameraBinderTestUtils.NO_ERROR && res != CameraBinderTestUtils.EOPNOTSUPP) {
+            if (res != CameraBinderTestUtils.NO_ERROR && res != -android.system.OsConstants.EOPNOTSUPP) {
                 fail("Camera service returned bad value when queried if it supports camera2 api: "
                         + res + " for camera ID " + cameraId);
             }
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTestUtils.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTestUtils.java
index 6be538a..5c4b23b 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTestUtils.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTestUtils.java
@@ -2,6 +2,7 @@
 package com.android.mediaframeworktest.integration;
 
 import static org.junit.Assert.assertNotNull;
+import static android.system.OsConstants.*;
 
 import android.content.Context;
 import android.content.pm.FeatureInfo;
@@ -18,11 +19,10 @@
     static final String CAMERA_SERVICE_BINDER_NAME = "media.camera";
 
     protected static final int USE_CALLING_UID = -1;
-    protected static final int BAD_VALUE = -22;
-    protected static final int INVALID_OPERATION = -38;
-    protected static final int ALREADY_EXISTS = -17;
+    protected static final int BAD_VALUE = -EINVAL;
+    protected static final int INVALID_OPERATION = -ENOSYS;
+    protected static final int ALREADY_EXISTS = -EEXIST;
     public static final int NO_ERROR = 0;
-    public static final int EOPNOTSUPP = -95;
     private final Context mContext;
 
     public CameraBinderTestUtils(Context context) {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsBinderDecoratorTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsBinderDecoratorTest.java
index 727af78..33c6388 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsBinderDecoratorTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsBinderDecoratorTest.java
@@ -27,6 +27,7 @@
 import static org.mockito.Mockito.*;
 import static android.hardware.camera2.utils.CameraBinderDecorator.*;
 import static android.hardware.camera2.CameraAccessException.*;
+import static android.system.OsConstants.*;
 
 import junit.framework.Assert;
 
@@ -78,9 +79,9 @@
             when(mock.doSomethingAlreadyExists()).thenReturn(ALREADY_EXISTS);
             when(mock.doSomethingBadValue()).thenReturn(BAD_VALUE);
             when(mock.doSomethingDeadObject()).thenReturn(DEAD_OBJECT);
-            when(mock.doSomethingBadPolicy()).thenReturn(EACCES);
-            when(mock.doSomethingDeviceBusy()).thenReturn(EBUSY);
-            when(mock.doSomethingNoSuchDevice()).thenReturn(ENODEV);
+            when(mock.doSomethingBadPolicy()).thenReturn(-EACCES);
+            when(mock.doSomethingDeviceBusy()).thenReturn(-EBUSY);
+            when(mock.doSomethingNoSuchDevice()).thenReturn(-ENODEV);
             when(mock.doSomethingUnknownErrorCode()).thenReturn(SOME_ARBITRARY_NEGATIVE_INT);
             when(mock.doSomethingThrowDeadObjectException()).thenThrow(new DeadObjectException());
             when(mock.doSomethingThrowTransactionTooLargeException()).thenThrow(
diff --git a/packages/DocumentsUI/res/values-af/strings.xml b/packages/DocumentsUI/res/values-af/strings.xml
index e967e3e..1599178 100644
--- a/packages/DocumentsUI/res/values-af/strings.xml
+++ b/packages/DocumentsUI/res/values-af/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Dokumente"</string>
     <string name="files_label" msgid="6051402950202690279">"Lêers"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Aflaaie"</string>
     <string name="title_open" msgid="4353228937663917801">"Maak oop vanuit"</string>
     <string name="title_save" msgid="2433679664882857999">"Stoor na"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Nuwe vouer"</string>
diff --git a/packages/DocumentsUI/res/values-bn-rBD/strings.xml b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
index 81a0a86..c757eaf 100644
--- a/packages/DocumentsUI/res/values-bn-rBD/strings.xml
+++ b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"দস্তাবেজগুলি"</string>
     <string name="files_label" msgid="6051402950202690279">"ফাইলগুলি"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"ডাউনলোডগুলি"</string>
     <string name="title_open" msgid="4353228937663917801">"এখান থেকে খুলুন"</string>
     <string name="title_save" msgid="2433679664882857999">"এতে সংরক্ষণ করুন"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"নতুন ফোল্ডার"</string>
diff --git a/packages/DocumentsUI/res/values-ca/strings.xml b/packages/DocumentsUI/res/values-ca/strings.xml
index 3b31947..f01624a 100644
--- a/packages/DocumentsUI/res/values-ca/strings.xml
+++ b/packages/DocumentsUI/res/values-ca/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Documents"</string>
     <string name="files_label" msgid="6051402950202690279">"Fitxers"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Baixades"</string>
     <string name="title_open" msgid="4353228937663917801">"Obre des de"</string>
     <string name="title_save" msgid="2433679664882857999">"Desa a"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Carpeta nova"</string>
diff --git a/packages/DocumentsUI/res/values-cs/strings.xml b/packages/DocumentsUI/res/values-cs/strings.xml
index 8938cd1..7c70809 100644
--- a/packages/DocumentsUI/res/values-cs/strings.xml
+++ b/packages/DocumentsUI/res/values-cs/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Dokumenty"</string>
     <string name="files_label" msgid="6051402950202690279">"Soubory"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Stahování"</string>
     <string name="title_open" msgid="4353228937663917801">"Otevřít"</string>
     <string name="title_save" msgid="2433679664882857999">"Uložit do"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Nová složka"</string>
diff --git a/packages/DocumentsUI/res/values-de/strings.xml b/packages/DocumentsUI/res/values-de/strings.xml
index 2c3f4f7..83eb8e0 100644
--- a/packages/DocumentsUI/res/values-de/strings.xml
+++ b/packages/DocumentsUI/res/values-de/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Dokumente"</string>
     <string name="files_label" msgid="6051402950202690279">"Dateien"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Downloads"</string>
     <string name="title_open" msgid="4353228937663917801">"Öffnen von"</string>
     <string name="title_save" msgid="2433679664882857999">"Speichern unter"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Neuer Ordner"</string>
diff --git a/packages/DocumentsUI/res/values-el/strings.xml b/packages/DocumentsUI/res/values-el/strings.xml
index 815585d..42959af 100644
--- a/packages/DocumentsUI/res/values-el/strings.xml
+++ b/packages/DocumentsUI/res/values-el/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Έγγραφα"</string>
     <string name="files_label" msgid="6051402950202690279">"Αρχεία"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Λήψεις"</string>
     <string name="title_open" msgid="4353228937663917801">"Άνοιγμα από"</string>
     <string name="title_save" msgid="2433679664882857999">"Αποθήκευση σε"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Νέος φάκελος"</string>
diff --git a/packages/DocumentsUI/res/values-es-rUS/strings.xml b/packages/DocumentsUI/res/values-es-rUS/strings.xml
index b54f62e..58090ce 100644
--- a/packages/DocumentsUI/res/values-es-rUS/strings.xml
+++ b/packages/DocumentsUI/res/values-es-rUS/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Documentos"</string>
     <string name="files_label" msgid="6051402950202690279">"Archivos"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Descargas"</string>
     <string name="title_open" msgid="4353228937663917801">"Abrir desde"</string>
     <string name="title_save" msgid="2433679664882857999">"Guardar en"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Carpeta nueva"</string>
diff --git a/packages/DocumentsUI/res/values-et-rEE/strings.xml b/packages/DocumentsUI/res/values-et-rEE/strings.xml
index a019d49..55d2503 100644
--- a/packages/DocumentsUI/res/values-et-rEE/strings.xml
+++ b/packages/DocumentsUI/res/values-et-rEE/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Dokumendid"</string>
     <string name="files_label" msgid="6051402950202690279">"Failid"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Allalaadimised"</string>
     <string name="title_open" msgid="4353228937663917801">"Ava:"</string>
     <string name="title_save" msgid="2433679664882857999">"Salvesta:"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Uus kaust"</string>
diff --git a/packages/DocumentsUI/res/values-fa/strings.xml b/packages/DocumentsUI/res/values-fa/strings.xml
index 3c58ac5..1989c62 100644
--- a/packages/DocumentsUI/res/values-fa/strings.xml
+++ b/packages/DocumentsUI/res/values-fa/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"اسناد"</string>
     <string name="files_label" msgid="6051402950202690279">"فایل‌ها"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"بارگیری‌ها"</string>
     <string name="title_open" msgid="4353228937663917801">"باز کردن از"</string>
     <string name="title_save" msgid="2433679664882857999">"ذخیره در"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"پوشه جدید"</string>
diff --git a/packages/DocumentsUI/res/values-fr-rCA/strings.xml b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
index e746d6e..ec81e67 100644
--- a/packages/DocumentsUI/res/values-fr-rCA/strings.xml
+++ b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Documents"</string>
     <string name="files_label" msgid="6051402950202690279">"Fichiers"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Téléchargements"</string>
     <string name="title_open" msgid="4353228937663917801">"Ouvrir à partir de"</string>
     <string name="title_save" msgid="2433679664882857999">"Enregistrer dans"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Nouveau dossier"</string>
diff --git a/packages/DocumentsUI/res/values-fr/strings.xml b/packages/DocumentsUI/res/values-fr/strings.xml
index 80c5a89..3d7ab32 100644
--- a/packages/DocumentsUI/res/values-fr/strings.xml
+++ b/packages/DocumentsUI/res/values-fr/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Docs"</string>
     <string name="files_label" msgid="6051402950202690279">"Fichiers"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Téléchargements"</string>
     <string name="title_open" msgid="4353228937663917801">"Ouvrir à partir de"</string>
     <string name="title_save" msgid="2433679664882857999">"Enregistrer sous"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Nouveau dossier"</string>
diff --git a/packages/DocumentsUI/res/values-gl-rES/strings.xml b/packages/DocumentsUI/res/values-gl-rES/strings.xml
index e24d64d..db98006 100644
--- a/packages/DocumentsUI/res/values-gl-rES/strings.xml
+++ b/packages/DocumentsUI/res/values-gl-rES/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Documentos"</string>
     <string name="files_label" msgid="6051402950202690279">"Ficheiros"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Descargas"</string>
     <string name="title_open" msgid="4353228937663917801">"Abrir desde"</string>
     <string name="title_save" msgid="2433679664882857999">"Gardar en"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Novo cartafol"</string>
diff --git a/packages/DocumentsUI/res/values-hr/strings.xml b/packages/DocumentsUI/res/values-hr/strings.xml
index 0916968..5884d6f 100644
--- a/packages/DocumentsUI/res/values-hr/strings.xml
+++ b/packages/DocumentsUI/res/values-hr/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Dokumenti"</string>
     <string name="files_label" msgid="6051402950202690279">"Datoteke"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Preuzimanja"</string>
     <string name="title_open" msgid="4353228937663917801">"Otvori iz"</string>
     <string name="title_save" msgid="2433679664882857999">"Spremi u"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Nova mapa"</string>
diff --git a/packages/DocumentsUI/res/values-hy-rAM/strings.xml b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
index 8d71582..7be66d3 100644
--- a/packages/DocumentsUI/res/values-hy-rAM/strings.xml
+++ b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Փաստաթղթեր"</string>
     <string name="files_label" msgid="6051402950202690279">"Ֆայլեր"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Ներբեռնումներ"</string>
     <string name="title_open" msgid="4353228937663917801">"Բացել այստեղից"</string>
     <string name="title_save" msgid="2433679664882857999">"Պահել այստեղ"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Նոր պանակ"</string>
diff --git a/packages/DocumentsUI/res/values-is-rIS/strings.xml b/packages/DocumentsUI/res/values-is-rIS/strings.xml
index 3b730d5..76dbe32 100644
--- a/packages/DocumentsUI/res/values-is-rIS/strings.xml
+++ b/packages/DocumentsUI/res/values-is-rIS/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Skjöl"</string>
     <string name="files_label" msgid="6051402950202690279">"Skrár"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Niðurhal"</string>
     <string name="title_open" msgid="4353228937663917801">"Opna frá"</string>
     <string name="title_save" msgid="2433679664882857999">"Vista í"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Ný mappa"</string>
diff --git a/packages/DocumentsUI/res/values-ja/strings.xml b/packages/DocumentsUI/res/values-ja/strings.xml
index b6b90d5..a954927 100644
--- a/packages/DocumentsUI/res/values-ja/strings.xml
+++ b/packages/DocumentsUI/res/values-ja/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"ドキュメント"</string>
     <string name="files_label" msgid="6051402950202690279">"ファイル"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"ダウンロード"</string>
     <string name="title_open" msgid="4353228937663917801">"次から開く:"</string>
     <string name="title_save" msgid="2433679664882857999">"次に保存:"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"新しいフォルダ"</string>
diff --git a/packages/DocumentsUI/res/values-ka-rGE/strings.xml b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
index b326910..ef91fab 100644
--- a/packages/DocumentsUI/res/values-ka-rGE/strings.xml
+++ b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"დოკუმენტები"</string>
     <string name="files_label" msgid="6051402950202690279">"ფაილები"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"ჩამოტვირთვები"</string>
     <string name="title_open" msgid="4353228937663917801">"გახსნა აქედან:"</string>
     <string name="title_save" msgid="2433679664882857999">"შენახვა აქ:"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"ახალი საქაღალდე"</string>
diff --git a/packages/DocumentsUI/res/values-ko/strings.xml b/packages/DocumentsUI/res/values-ko/strings.xml
index 3356a92..4074841 100644
--- a/packages/DocumentsUI/res/values-ko/strings.xml
+++ b/packages/DocumentsUI/res/values-ko/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"문서"</string>
     <string name="files_label" msgid="6051402950202690279">"파일"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"다운로드"</string>
     <string name="title_open" msgid="4353228937663917801">"열기:"</string>
     <string name="title_save" msgid="2433679664882857999">"저장 위치:"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"새 폴더"</string>
diff --git a/packages/DocumentsUI/res/values-ky-rKG/strings.xml b/packages/DocumentsUI/res/values-ky-rKG/strings.xml
index d75f522..aecf542 100644
--- a/packages/DocumentsUI/res/values-ky-rKG/strings.xml
+++ b/packages/DocumentsUI/res/values-ky-rKG/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Документтер"</string>
     <string name="files_label" msgid="6051402950202690279">"Файлдар"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Жүктөөлөр"</string>
     <string name="title_open" msgid="4353228937663917801">"Кийинкиден ачуу:"</string>
     <string name="title_save" msgid="2433679664882857999">"Кийинкиге сактоо:"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Жаңы куржун"</string>
diff --git a/packages/DocumentsUI/res/values-mk-rMK/strings.xml b/packages/DocumentsUI/res/values-mk-rMK/strings.xml
index 8f15edd..2d8be1b 100644
--- a/packages/DocumentsUI/res/values-mk-rMK/strings.xml
+++ b/packages/DocumentsUI/res/values-mk-rMK/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Документи"</string>
     <string name="files_label" msgid="6051402950202690279">"Датотеки"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Преземања"</string>
     <string name="title_open" msgid="4353228937663917801">"Отвори од"</string>
     <string name="title_save" msgid="2433679664882857999">"Зачувај во"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Нова папка"</string>
diff --git a/packages/DocumentsUI/res/values-mn-rMN/strings.xml b/packages/DocumentsUI/res/values-mn-rMN/strings.xml
index f4a5d96..d0e43f4 100644
--- a/packages/DocumentsUI/res/values-mn-rMN/strings.xml
+++ b/packages/DocumentsUI/res/values-mn-rMN/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Документүүд"</string>
     <string name="files_label" msgid="6051402950202690279">"Файл"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Таталт"</string>
     <string name="title_open" msgid="4353228937663917801">"Нээх"</string>
     <string name="title_save" msgid="2433679664882857999">"Хадгалах"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Шинэ фолдер"</string>
diff --git a/packages/DocumentsUI/res/values-ms-rMY/strings.xml b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
index 266ca93..ea88ef6 100644
--- a/packages/DocumentsUI/res/values-ms-rMY/strings.xml
+++ b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Dokumen"</string>
     <string name="files_label" msgid="6051402950202690279">"Fail"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Muat turun"</string>
     <string name="title_open" msgid="4353228937663917801">"Buka dari"</string>
     <string name="title_save" msgid="2433679664882857999">"Simpan ke"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Folder baharu"</string>
diff --git a/packages/DocumentsUI/res/values-nb/strings.xml b/packages/DocumentsUI/res/values-nb/strings.xml
index 591d123..01dda74 100644
--- a/packages/DocumentsUI/res/values-nb/strings.xml
+++ b/packages/DocumentsUI/res/values-nb/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Dokumenter"</string>
     <string name="files_label" msgid="6051402950202690279">"Filer"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Nedlastinger"</string>
     <string name="title_open" msgid="4353228937663917801">"Åpne fra"</string>
     <string name="title_save" msgid="2433679664882857999">"Lagre i"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Ny mappe"</string>
diff --git a/packages/DocumentsUI/res/values-nl/strings.xml b/packages/DocumentsUI/res/values-nl/strings.xml
index 701c06c..5948167 100644
--- a/packages/DocumentsUI/res/values-nl/strings.xml
+++ b/packages/DocumentsUI/res/values-nl/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Documenten"</string>
     <string name="files_label" msgid="6051402950202690279">"Bestanden"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Downloads"</string>
     <string name="title_open" msgid="4353228937663917801">"Openen vanuit"</string>
     <string name="title_save" msgid="2433679664882857999">"Opslaan in"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Nieuwe map"</string>
diff --git a/packages/DocumentsUI/res/values-pl/strings.xml b/packages/DocumentsUI/res/values-pl/strings.xml
index 586e263..3fd3266 100644
--- a/packages/DocumentsUI/res/values-pl/strings.xml
+++ b/packages/DocumentsUI/res/values-pl/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Dokumenty"</string>
     <string name="files_label" msgid="6051402950202690279">"Pliki"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Pobrane"</string>
     <string name="title_open" msgid="4353228937663917801">"Otwórz z"</string>
     <string name="title_save" msgid="2433679664882857999">"Zapisz w"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Nowy folder"</string>
diff --git a/packages/DocumentsUI/res/values-pt-rPT/strings.xml b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
index a1b82ab..02cd2dd 100644
--- a/packages/DocumentsUI/res/values-pt-rPT/strings.xml
+++ b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Documentos"</string>
     <string name="files_label" msgid="6051402950202690279">"Ficheiros"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Transferências"</string>
     <string name="title_open" msgid="4353228937663917801">"Abrir de"</string>
     <string name="title_save" msgid="2433679664882857999">"Guardar em"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Nova pasta"</string>
diff --git a/packages/DocumentsUI/res/values-ro/strings.xml b/packages/DocumentsUI/res/values-ro/strings.xml
index 4c4e6fa..5d32285 100644
--- a/packages/DocumentsUI/res/values-ro/strings.xml
+++ b/packages/DocumentsUI/res/values-ro/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Documente"</string>
     <string name="files_label" msgid="6051402950202690279">"Fișiere"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Descărcări"</string>
     <string name="title_open" msgid="4353228937663917801">"Deschideți din"</string>
     <string name="title_save" msgid="2433679664882857999">"Salvați în"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Dosar nou"</string>
diff --git a/packages/DocumentsUI/res/values-sl/strings.xml b/packages/DocumentsUI/res/values-sl/strings.xml
index 20fc5c5..6da1290 100644
--- a/packages/DocumentsUI/res/values-sl/strings.xml
+++ b/packages/DocumentsUI/res/values-sl/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Dokumenti"</string>
     <string name="files_label" msgid="6051402950202690279">"Datoteke"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Prenosi"</string>
     <string name="title_open" msgid="4353228937663917801">"Odpri iz mape"</string>
     <string name="title_save" msgid="2433679664882857999">"Shrani v"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Nova mapa"</string>
diff --git a/packages/DocumentsUI/res/values-sq-rAL/strings.xml b/packages/DocumentsUI/res/values-sq-rAL/strings.xml
index 63c57a9..b880bb4 100644
--- a/packages/DocumentsUI/res/values-sq-rAL/strings.xml
+++ b/packages/DocumentsUI/res/values-sq-rAL/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Dokumente"</string>
     <string name="files_label" msgid="6051402950202690279">"Skedarët"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Shkarkimet"</string>
     <string name="title_open" msgid="4353228937663917801">"Hap nga"</string>
     <string name="title_save" msgid="2433679664882857999">"Ruaje te"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Dosje e re"</string>
diff --git a/packages/DocumentsUI/res/values-sr/strings.xml b/packages/DocumentsUI/res/values-sr/strings.xml
index 2956dc3..93a1cf6 100644
--- a/packages/DocumentsUI/res/values-sr/strings.xml
+++ b/packages/DocumentsUI/res/values-sr/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Документи"</string>
     <string name="files_label" msgid="6051402950202690279">"Датотеке"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Преузимања"</string>
     <string name="title_open" msgid="4353228937663917801">"Отвори са"</string>
     <string name="title_save" msgid="2433679664882857999">"Сачувај у"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Нови директоријум"</string>
diff --git a/packages/DocumentsUI/res/values-sv/strings.xml b/packages/DocumentsUI/res/values-sv/strings.xml
index c0af8fc..63da2c6 100644
--- a/packages/DocumentsUI/res/values-sv/strings.xml
+++ b/packages/DocumentsUI/res/values-sv/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Dokument"</string>
     <string name="files_label" msgid="6051402950202690279">"Filer"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Nedladdningar"</string>
     <string name="title_open" msgid="4353228937663917801">"Öppna från"</string>
     <string name="title_save" msgid="2433679664882857999">"Spara till"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Ny mapp"</string>
diff --git a/packages/DocumentsUI/res/values-ta-rIN/strings.xml b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
index af53217..87cb68d 100644
--- a/packages/DocumentsUI/res/values-ta-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"ஆவணங்கள்"</string>
     <string name="files_label" msgid="6051402950202690279">"கோப்புகள்"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"இறக்கங்கள்"</string>
     <string name="title_open" msgid="4353228937663917801">"இதில் திற"</string>
     <string name="title_save" msgid="2433679664882857999">"இதில் சேமி"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"புதிய கோப்புறை"</string>
diff --git a/packages/DocumentsUI/res/values-th/strings.xml b/packages/DocumentsUI/res/values-th/strings.xml
index 0403928..dfb423e 100644
--- a/packages/DocumentsUI/res/values-th/strings.xml
+++ b/packages/DocumentsUI/res/values-th/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"เอกสาร"</string>
     <string name="files_label" msgid="6051402950202690279">"ไฟล์"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"การดาวน์โหลด"</string>
     <string name="title_open" msgid="4353228937663917801">"เปิดจาก"</string>
     <string name="title_save" msgid="2433679664882857999">"บันทึกไปยัง"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"โฟลเดอร์ใหม่"</string>
diff --git a/packages/DocumentsUI/res/values-tl/strings.xml b/packages/DocumentsUI/res/values-tl/strings.xml
index b83213b..813b39a 100644
--- a/packages/DocumentsUI/res/values-tl/strings.xml
+++ b/packages/DocumentsUI/res/values-tl/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Mga Dokumento"</string>
     <string name="files_label" msgid="6051402950202690279">"Mga File"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Mga Download"</string>
     <string name="title_open" msgid="4353228937663917801">"Buksan mula sa"</string>
     <string name="title_save" msgid="2433679664882857999">"I-save sa"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Bagong folder"</string>
diff --git a/packages/DocumentsUI/res/values-tr/strings.xml b/packages/DocumentsUI/res/values-tr/strings.xml
index 5caa5df..90794a2 100644
--- a/packages/DocumentsUI/res/values-tr/strings.xml
+++ b/packages/DocumentsUI/res/values-tr/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Dokümanlar"</string>
     <string name="files_label" msgid="6051402950202690279">"Dosyalar"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"İndirilenler"</string>
     <string name="title_open" msgid="4353228937663917801">"Şuradan aç:"</string>
     <string name="title_save" msgid="2433679664882857999">"Şuraya kaydet:"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Yeni klasör"</string>
diff --git a/packages/DocumentsUI/res/values-uk/strings.xml b/packages/DocumentsUI/res/values-uk/strings.xml
index b111daf..a8278d9 100644
--- a/packages/DocumentsUI/res/values-uk/strings.xml
+++ b/packages/DocumentsUI/res/values-uk/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Документи"</string>
     <string name="files_label" msgid="6051402950202690279">"Файли"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Завантаження"</string>
     <string name="title_open" msgid="4353228937663917801">"Відкрити"</string>
     <string name="title_save" msgid="2433679664882857999">"Зберегти в"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Нова папка"</string>
diff --git a/packages/DocumentsUI/res/values-ur-rPK/strings.xml b/packages/DocumentsUI/res/values-ur-rPK/strings.xml
index 6ceb77f..d8caa37 100644
--- a/packages/DocumentsUI/res/values-ur-rPK/strings.xml
+++ b/packages/DocumentsUI/res/values-ur-rPK/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"دستاویزات"</string>
     <string name="files_label" msgid="6051402950202690279">"فائلیں"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"ڈاؤن لوڈز"</string>
     <string name="title_open" msgid="4353228937663917801">"کھولیں از"</string>
     <string name="title_save" msgid="2433679664882857999">"اس میں محفوظ کریں"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"نیا فولڈر"</string>
diff --git a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
index bf2639e..b944736 100644
--- a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
+++ b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"Hujjatlar"</string>
     <string name="files_label" msgid="6051402950202690279">"Fayllar"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"Yuklanmalar"</string>
     <string name="title_open" msgid="4353228937663917801">"Ochish"</string>
     <string name="title_save" msgid="2433679664882857999">"Saqlash"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"Yangi jild"</string>
diff --git a/packages/DocumentsUI/res/values-zh-rCN/strings.xml b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
index bcd26c2..9901abf 100644
--- a/packages/DocumentsUI/res/values-zh-rCN/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
@@ -18,8 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"文档"</string>
     <string name="files_label" msgid="6051402950202690279">"文件"</string>
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
+    <string name="downloads_label" msgid="959113951084633612">"下载"</string>
     <string name="title_open" msgid="4353228937663917801">"打开文件"</string>
     <string name="title_save" msgid="2433679664882857999">"保存文件"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"新建文件夹"</string>
diff --git a/packages/DocumentsUI/res/values-zh-rHK/strings.xml b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
index cd02880..9cfba1d 100644
--- a/packages/DocumentsUI/res/values-zh-rHK/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
@@ -18,7 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="2783841764617238354">"文件"</string>
     <string name="files_label" msgid="6051402950202690279">"檔案"</string>
-    <string name="downloads_label" msgid="959113951084633612">"下載內容"</string>
+    <string name="downloads_label" msgid="959113951084633612">"下載"</string>
     <string name="title_open" msgid="4353228937663917801">"開啟檔案"</string>
     <string name="title_save" msgid="2433679664882857999">"儲存至"</string>
     <string name="menu_create_dir" msgid="2547620241173881754">"新增資料夾"</string>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index 2e7c908..770d011 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -17,7 +17,6 @@
 package com.android.documentsui.dirlist;
 
 import static com.android.documentsui.Shared.DEBUG;
-import static com.android.documentsui.State.ACTION_CREATE;
 import static com.android.documentsui.State.ACTION_MANAGE;
 import static com.android.documentsui.State.MODE_GRID;
 import static com.android.documentsui.State.MODE_LIST;
@@ -28,6 +27,7 @@
 import static com.android.documentsui.model.DocumentInfo.getCursorString;
 import static com.android.internal.util.Preconditions.checkNotNull;
 import static com.android.internal.util.Preconditions.checkState;
+import static com.google.common.base.Preconditions.checkArgument;
 
 import android.app.Activity;
 import android.app.ActivityManager;
@@ -89,6 +89,7 @@
 import android.widget.TextView;
 
 import com.android.documentsui.BaseActivity;
+import com.android.documentsui.BaseActivity.DocumentContext;
 import com.android.documentsui.CopyService;
 import com.android.documentsui.DirectoryLoader;
 import com.android.documentsui.DirectoryResult;
@@ -101,20 +102,18 @@
 import com.android.documentsui.MessageBar;
 import com.android.documentsui.MimePredicate;
 import com.android.documentsui.ProviderExecutor;
+import com.android.documentsui.ProviderExecutor.Preemptable;
 import com.android.documentsui.R;
 import com.android.documentsui.RecentLoader;
 import com.android.documentsui.RecentsProvider;
+import com.android.documentsui.RecentsProvider.StateColumns;
 import com.android.documentsui.RootCursorWrapper;
 import com.android.documentsui.RootsCache;
 import com.android.documentsui.Shared;
+import com.android.documentsui.Shared;
 import com.android.documentsui.Snackbars;
 import com.android.documentsui.State;
 import com.android.documentsui.ThumbnailCache;
-import com.android.documentsui.BaseActivity.DocumentContext;
-import com.android.documentsui.ProviderExecutor.Preemptable;
-import com.android.documentsui.Shared;
-import com.android.documentsui.RecentsProvider.StateColumns;
-import com.android.documentsui.dirlist.MultiSelectManager.Callback;
 import com.android.documentsui.dirlist.MultiSelectManager.Selection;
 import com.android.documentsui.model.DocumentInfo;
 import com.android.documentsui.model.DocumentStack;
@@ -317,12 +316,8 @@
         mAdapter = new DocumentsAdapter(context);
         mRecView.setAdapter(mAdapter);
 
-        mDefaultItemColor = context.getResources().getColor(android.R.color.transparent);
-        // Get the accent color.
-        TypedValue selColor = new TypedValue();
-        context.getTheme().resolveAttribute(android.R.attr.colorAccent, selColor, true);
-        // Set the opacity to 10%.
-        mSelectedItemColor = (selColor.data & 0x00ffffff) | 0x16000000;
+        mDefaultItemColor = context.getResources().getColor(R.color.item_doc_background);
+        mSelectedItemColor = context.getResources().getColor(R.color.item_doc_background_selected);
 
         GestureDetector.SimpleOnGestureListener listener =
                 new GestureDetector.SimpleOnGestureListener() {
@@ -770,7 +765,9 @@
                     return true;
 
                 case R.id.menu_copy_to_clipboard:
-                    copySelectionToClipboard(selection);
+                    if (!selection.isEmpty()) {
+                        copySelectionToClipboard(selection);
+                    }
                     return true;
 
                 case R.id.menu_select_all:
@@ -942,6 +939,7 @@
 
         public void setSelected(boolean selected) {
             itemView.setActivated(selected);
+            itemView.setBackgroundColor(selected ? mSelectedItemColor : mDefaultItemColor);
         }
 
         @Override
@@ -1359,11 +1357,14 @@
     }
 
     public void copySelectedToClipboard() {
-        Selection sel = mSelectionManager.getSelection(new Selection());
-        copySelectionToClipboard(sel);
+        Selection selection = mSelectionManager.getSelection(new Selection());
+        if (!selection.isEmpty()) {
+            copySelectionToClipboard(selection);
+        }
     }
 
-    void copySelectionToClipboard(Selection items) {
+    void copySelectionToClipboard(Selection selection) {
+        checkArgument(!selection.isEmpty());
         new GetDocumentsTask() {
             @Override
             void onDocumentsReady(List<DocumentInfo> docs) {
@@ -1374,7 +1375,7 @@
                                 R.plurals.clipboard_files_clipped, docs.size(), docs.size()),
                                 Snackbar.LENGTH_SHORT).show();
             }
-        }.execute(items);
+        }.execute(selection);
     }
 
     public void pasteFromClipboard() {
diff --git a/packages/MtpDocumentsProvider/Android.mk b/packages/MtpDocumentsProvider/Android.mk
index ec18463..3c2fa36 100644
--- a/packages/MtpDocumentsProvider/Android.mk
+++ b/packages/MtpDocumentsProvider/Android.mk
@@ -5,6 +5,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_PACKAGE_NAME := MtpDocumentsProvider
 LOCAL_CERTIFICATE := media
+LOCAL_PRIVILEGED_MODULE := true
 
 include $(BUILD_PACKAGE)
 include $(LOCAL_PATH)/tests/Android.mk
diff --git a/packages/MtpDocumentsProvider/AndroidManifest.xml b/packages/MtpDocumentsProvider/AndroidManifest.xml
index 0172a4f..2090d20 100644
--- a/packages/MtpDocumentsProvider/AndroidManifest.xml
+++ b/packages/MtpDocumentsProvider/AndroidManifest.xml
@@ -3,29 +3,26 @@
           package="com.android.mtp"
           android:sharedUserId="android.media">
     <uses-feature android:name="android.hardware.usb.host" />
+    <uses-permission android:name="android.permission.MANAGE_USB" />
     <application android:label="@string/app_label">
         <provider
             android:name=".MtpDocumentsProvider"
             android:authorities="com.android.mtp.documents"
             android:grantUriPermissions="true"
             android:exported="true"
-            android:permission="android.permission.MANAGE_DOCUMENTS"
-            android:enabled="false">
+            android:permission="android.permission.MANAGE_DOCUMENTS">
             <intent-filter>
                 <action android:name="android.content.action.DOCUMENTS_PROVIDER" />
             </intent-filter>
         </provider>
-        <activity android:name=".ReceiverActivity"
-                  android:theme="@android:style/Theme.NoDisplay"
-                  android:screenOrientation="locked"
-                  android:excludeFromRecents="true"
-                  android:enabled="false">
+        <service android:name=".MtpDocumentsService" />
+        <receiver android:name=".UsbIntentReceiver" android:exported="true">
             <intent-filter>
                 <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
+                <action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
             </intent-filter>
             <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
-                       android:resource="@xml/device_filter" />
-        </activity>
-        <service android:name=".MtpDocumentsService"></service>
+                    android:resource="@xml/device_filter" />
+        </receiver>
     </application>
 </manifest>
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
index 9511e15..d5f00e6 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
@@ -253,9 +253,15 @@
         mRootScanner.notifyChange();
     }
 
-    boolean hasOpenedDevices() {
+    int[] getOpenedDeviceIds() {
         synchronized (mDeviceListLock) {
-            return mMtpManager.getOpenedDeviceIds().length != 0;
+            return mMtpManager.getOpenedDeviceIds();
+        }
+    }
+
+    String getDeviceName(int deviceId) throws IOException {
+        synchronized (mDeviceListLock) {
+            return mMtpManager.getDeviceName(deviceId);
         }
     }
 
@@ -308,7 +314,7 @@
         getDeviceToolkit(deviceId).mDocumentLoader.clearTasks();
         mDeviceToolkits.remove(deviceId);
         mMtpManager.closeDevice(deviceId);
-        if (!hasOpenedDevices()) {
+        if (getOpenedDeviceIds().length == 0) {
             mRootScanner.pause();
         }
     }
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java
index 9b3c20f..b0cff83 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsService.java
@@ -16,16 +16,16 @@
 
 package com.android.mtp;
 
+import android.app.Notification;
 import android.app.Service;
-import android.content.BroadcastReceiver;
-import android.content.Context;
+import android.app.NotificationManager;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.hardware.usb.UsbDevice;
-import android.hardware.usb.UsbManager;
 import android.os.IBinder;
 import android.util.Log;
 
+import com.android.internal.util.Preconditions;
+
 import java.io.IOException;
 
 /**
@@ -34,10 +34,12 @@
  * starts to run when the first MTP device is opened, and stops when the last MTP device is closed.
  */
 public class MtpDocumentsService extends Service {
-    static final String ACTION_OPEN_DEVICE = "com.android.mtp.action.ACTION_OPEN_DEVICE";
+    static final String ACTION_OPEN_DEVICE = "com.android.mtp.OPEN_DEVICE";
+    static final String ACTION_CLOSE_DEVICE = "com.android.mtp.CLOSE_DEVICE";
     static final String EXTRA_DEVICE = "device";
+    private static final int FOREGROUND_NOTIFICATION_ID = 1;
 
-    Receiver mReceiver;
+    NotificationManager mNotificationManager;
 
     @Override
     public IBinder onBind(Intent intent) {
@@ -48,60 +50,89 @@
     @Override
     public void onCreate() {
         super.onCreate();
-        final IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_DEVICE_DETACHED);
-        mReceiver = new Receiver();
-        registerReceiver(mReceiver, filter);
+        mNotificationManager = getSystemService(NotificationManager.class);
     }
 
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
         // If intent is null, the service was restarted.
         if (intent != null) {
-            if (intent.getAction().equals(ACTION_OPEN_DEVICE)) {
-                final UsbDevice device = intent.<UsbDevice>getParcelableExtra(EXTRA_DEVICE);
-                try {
-                    final MtpDocumentsProvider provider = MtpDocumentsProvider.getInstance();
-                    provider.openDevice(device.getDeviceId());
-                    return START_STICKY;
-                } catch (IOException error) {
-                    Log.e(MtpDocumentsProvider.TAG, error.getMessage());
+            final MtpDocumentsProvider provider = MtpDocumentsProvider.getInstance();
+            final UsbDevice device = intent.<UsbDevice>getParcelableExtra(EXTRA_DEVICE);
+            try {
+                Preconditions.checkNotNull(device);
+                switch (intent.getAction()) {
+                    case ACTION_OPEN_DEVICE:
+                        provider.openDevice(device.getDeviceId());
+                        break;
+
+                    case ACTION_CLOSE_DEVICE:
+                        provider.closeDevice(device.getDeviceId());
+                        break;
+
+                    default:
+                        throw new IllegalArgumentException("Received unknown intent action.");
                 }
-            } else {
-                Log.e(MtpDocumentsProvider.TAG, "Received unknown intent action.");
+            } catch (IOException | InterruptedException | IllegalArgumentException error) {
+                logErrorMessage(error);
             }
+        } else {
+            // TODO: Fetch devices again.
         }
-        stopSelfIfNeeded();
-        return Service.START_NOT_STICKY;
+
+        return updateForegroundState() ? START_STICKY : START_NOT_STICKY;
     }
 
-    @Override
-    public void onDestroy() {
-        unregisterReceiver(mReceiver);
-        mReceiver = null;
-        super.onDestroy();
-    }
-
-    private void stopSelfIfNeeded() {
+    /**
+     * Updates the foreground state of the service.
+     * @return Whether the service is foreground or not.
+     */
+    private boolean updateForegroundState() {
         final MtpDocumentsProvider provider = MtpDocumentsProvider.getInstance();
-        if (!provider.hasOpenedDevices()) {
+        final int[] deviceIds = provider.getOpenedDeviceIds();
+        String message = null;
+        if (deviceIds.length != 0) {
+            // TODO: Localize the message.
+            // TODO: Add buttons "Open in Files" and "Open in Apps" if needed.
+            if (deviceIds.length > 1) {
+                message = deviceIds.length + " devices are being connected.";
+            } else {
+                try {
+                    message = provider.getDeviceName(deviceIds[0]) + " is being connected.";
+                } catch (IOException exp) {
+                    logErrorMessage(exp);
+                    // If we failed to obtain device name, it looks the device is unusable.
+                    // Because this is the last device we opened, we should hide the notification
+                    // for the case.
+                    try {
+                        provider.closeDevice(deviceIds[0]);
+                    } catch (IOException | InterruptedException closeError) {
+                        logErrorMessage(closeError);
+                    }
+                }
+            }
+        }
+        if (message != null) {
+            final Notification notification = new Notification.Builder(this)
+                    .setContentTitle(message)
+                    .setSmallIcon(android.R.drawable.ic_menu_camera)
+                    .setCategory(Notification.CATEGORY_SYSTEM)
+                    .setPriority(Notification.PRIORITY_LOW)
+                    .build();
+            startForeground(FOREGROUND_NOTIFICATION_ID, notification);
+            return true;
+        } else {
+            stopForeground(true /* removeNotification */);
             stopSelf();
+            return false;
         }
     }
 
-    private class Receiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(intent.getAction())) {
-                final UsbDevice device =
-                        (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
-                final MtpDocumentsProvider provider = MtpDocumentsProvider.getInstance();
-                try {
-                    provider.closeDevice(device.getDeviceId());
-                } catch (IOException | InterruptedException error) {
-                    Log.e(MtpDocumentsProvider.TAG, error.getMessage());
-                }
-                stopSelfIfNeeded();
-            }
+    private static void logErrorMessage(Exception exp) {
+        if (exp.getMessage() != null) {
+            Log.e(MtpDocumentsProvider.TAG, exp.getMessage());
+        } else {
+            Log.e(MtpDocumentsProvider.TAG, exp.toString());
         }
     }
 }
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
index cd52f31..e7f94b7 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
@@ -32,7 +32,6 @@
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
-import java.util.ArrayList;
 
 /**
  * The model wrapping android.mtp API.
@@ -62,8 +61,10 @@
         }
 
         if (!mManager.hasPermission(rawDevice)) {
-            // Permission should be obtained via app selection dialog for intent.
-            throw new IOException("No parmission to operate USB device.");
+            mManager.grantPermission(rawDevice);
+            if (!mManager.hasPermission(rawDevice)) {
+                throw new IOException("Failed to grant a device permission.");
+            }
         }
 
         final MtpDevice device = new MtpDevice(rawDevice);
@@ -99,6 +100,10 @@
         return result;
     }
 
+    String getDeviceName(int deviceId) throws IOException {
+        return getDevice(deviceId).getDeviceInfo().getModel();
+    }
+
     MtpRoot[] getRoots(int deviceId) throws IOException {
         final MtpDevice device = getDevice(deviceId);
         synchronized (device) {
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/ReceiverActivity.java b/packages/MtpDocumentsProvider/src/com/android/mtp/ReceiverActivity.java
deleted file mode 100644
index 3ad2397..0000000
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/ReceiverActivity.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mtp;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.hardware.usb.UsbManager;
-import android.os.Bundle;
-
-/**
- * Invisible activity to receive intents.
- * To show the application chooser for the UsbManager.ACTION_USB_DEVICE_ATTACHED intent, the intent
- * should be received by activity. The activity has NoDisplay theme and immediately terminate after
- * routing intent to MtpDocumentsService.
- */
-public class ReceiverActivity extends Activity {
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(getIntent().getAction())) {
-            final Intent serviceIntent = new Intent(
-                    MtpDocumentsService.ACTION_OPEN_DEVICE,
-                    null,
-                    this,
-                    MtpDocumentsService.class);
-            serviceIntent.putExtra(
-                    UsbManager.EXTRA_DEVICE,
-                    getIntent().getParcelableExtra(UsbManager.EXTRA_DEVICE));
-            startService(serviceIntent);
-        }
-        finish();
-    }
-}
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/UsbIntentReceiver.java b/packages/MtpDocumentsProvider/src/com/android/mtp/UsbIntentReceiver.java
new file mode 100644
index 0000000..0ac130e
--- /dev/null
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/UsbIntentReceiver.java
@@ -0,0 +1,45 @@
+/*
+ * 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.mtp;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbManager;
+import android.net.Uri;
+
+public class UsbIntentReceiver extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        final UsbDevice device = intent.getExtras().getParcelable(UsbManager.EXTRA_DEVICE);
+        switch (intent.getAction()) {
+            case UsbManager.ACTION_USB_DEVICE_ATTACHED:
+                startService(context, MtpDocumentsService.ACTION_OPEN_DEVICE, device);
+                break;
+            case UsbManager.ACTION_USB_DEVICE_DETACHED:
+                startService(context, MtpDocumentsService.ACTION_CLOSE_DEVICE, device);
+                break;
+        }
+    }
+
+    private void startService(Context context, String action, UsbDevice device) {
+        final Intent intent = new Intent(action, Uri.EMPTY, context, MtpDocumentsService.class);
+        intent.putExtra(MtpDocumentsService.EXTRA_DEVICE, device);
+        context.startService(intent);
+    }
+}
diff --git a/packages/SettingsLib/res/values-af/arrays.xml b/packages/SettingsLib/res/values-af/arrays.xml
index f7b0e4d..c886476 100644
--- a/packages/SettingsLib/res/values-af/arrays.xml
+++ b/packages/SettingsLib/res/values-af/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Nie meer as 3 prosesse nie"</item>
     <item msgid="7899496259191969307">"Nie meer as 4 prosesse nie"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Laai tans"</item>
+    <item msgid="5220695614993094977">"MTP (Media-oordrag-protokol)"</item>
+    <item msgid="2086000968159047375">"PTP (Prentoordrag-protokol)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB-ethernet)"</item>
+    <item msgid="1718924214939774352">"Oudiobron"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index f281489..302ba04 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Persoonlik"</string>
     <string name="category_work" msgid="8699184680584175622">"Werk"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Ontwikkelaaropsies"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Aktiveer ontwikkelaaropsies"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Stel opsies vir programontwikkeling"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Ontwikkelaar-opsies is nie beskikbaar vir hierdie gebruiker nie"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"VPN-instellings is nie vir hierdie gebruiker beskikbaar nie"</string>
diff --git a/packages/SettingsLib/res/values-bn-rBD/arrays.xml b/packages/SettingsLib/res/values-bn-rBD/arrays.xml
index a2e811b..7729a4d 100644
--- a/packages/SettingsLib/res/values-bn-rBD/arrays.xml
+++ b/packages/SettingsLib/res/values-bn-rBD/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"৩টি প্রক্রিয়ার বেশি নয়"</item>
     <item msgid="7899496259191969307">"৪টি প্রক্রিয়ার বেশি নয়"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"চার্জ হচ্ছে"</item>
+    <item msgid="5220695614993094977">"MTP (মিডিয়া ট্রান্সফার প্রোটোকল)"</item>
+    <item msgid="2086000968159047375">"PTP (পিকচার ট্রান্সফার প্রোটোকল)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB ইথারনেট)"</item>
+    <item msgid="1718924214939774352">"অডিও উৎস"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-bn-rBD/strings.xml b/packages/SettingsLib/res/values-bn-rBD/strings.xml
index 2434f8e..5c83183 100644
--- a/packages/SettingsLib/res/values-bn-rBD/strings.xml
+++ b/packages/SettingsLib/res/values-bn-rBD/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"ব্যক্তিগত"</string>
     <string name="category_work" msgid="8699184680584175622">"কর্মক্ষেত্র"</string>
     <string name="development_settings_title" msgid="215179176067683667">"বিকাশকারী বিকল্পগুলি"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"বিকাশকারী বিকল্পগুলি সক্ষম করুন"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"অ্যাপ্লিকেশান উন্নয়নের জন্য বিকল্পগুলি সেট করুন"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"এই ব্যবহারকারীর জন্য বিকাশকারী বিকল্পগুলি উপলব্ধ নয়"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"এই ব্যবহারকারীর জন্য VPN সেটিংস উপলব্ধ নয়"</string>
diff --git a/packages/SettingsLib/res/values-ca/arrays.xml b/packages/SettingsLib/res/values-ca/arrays.xml
index 9542af1..ab80ccc 100644
--- a/packages/SettingsLib/res/values-ca/arrays.xml
+++ b/packages/SettingsLib/res/values-ca/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Com a màxim 3 processos"</item>
     <item msgid="7899496259191969307">"Com a màxim 4 processos"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"S\'està carregant"</item>
+    <item msgid="5220695614993094977">"MTP (protocol de transferència de fitxers multimèdia)"</item>
+    <item msgid="2086000968159047375">"PTP (protocol de transferència d\'imatges)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
+    <item msgid="1718924214939774352">"Font d\'àudio"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 065efd9..71a331d2 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Personal"</string>
     <string name="category_work" msgid="8699184680584175622">"Feina"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Opcions per a desenvolupadors"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Activa les opcions per a desenvolupadors"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Defineix les opcions per al desenvolupament d\'aplicacions"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Les opcions per a desenvolupadors no estan disponibles per a aquest usuari."</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"La configuració de la VPN no està disponible per a aquest usuari."</string>
diff --git a/packages/SettingsLib/res/values-cs/arrays.xml b/packages/SettingsLib/res/values-cs/arrays.xml
index 3f786b8..d46781a 100644
--- a/packages/SettingsLib/res/values-cs/arrays.xml
+++ b/packages/SettingsLib/res/values-cs/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Maximálně 3 procesy"</item>
     <item msgid="7899496259191969307">"Maximálně 4 procesy"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Nabíjení"</item>
+    <item msgid="5220695614993094977">"MTP (Media Transfer Protocol)"</item>
+    <item msgid="2086000968159047375">"PTP (Picture Transfer Protocol)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
+    <item msgid="1718924214939774352">"Zdroj zvuku"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 951708e..8ec5e25 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Osobní"</string>
     <string name="category_work" msgid="8699184680584175622">"Pracovní"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Pro vývojáře"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Aktivovat možnosti pro vývojáře"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Umožňuje nastavit možnosti pro vývoj aplikací"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Pro tohoto uživatele jsou možnosti vývojáře nedostupné."</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Nastavení sítě VPN pro tohoto uživatele není dostupné."</string>
diff --git a/packages/SettingsLib/res/values-de/arrays.xml b/packages/SettingsLib/res/values-de/arrays.xml
index faa1d24..d2a7f0d 100644
--- a/packages/SettingsLib/res/values-de/arrays.xml
+++ b/packages/SettingsLib/res/values-de/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Höchstens 3 Prozesse"</item>
     <item msgid="7899496259191969307">"Höchstens 4 Prozesse"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Wird aufgeladen"</item>
+    <item msgid="5220695614993094977">"MTP (Media Transfer Protocol)"</item>
+    <item msgid="2086000968159047375">"PTP (Picture Transfer Protocol)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB-Ethernet)"</item>
+    <item msgid="1718924214939774352">"Audioquelle"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index a78d00d..9b60b20 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Nutzer"</string>
     <string name="category_work" msgid="8699184680584175622">"Geschäftlich"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Entwickleroptionen"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Entwickleroptionen aktivieren"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Optionen zur App-Entwicklung festlegen"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Entwickleroptionen sind für diesen Nutzer nicht verfügbar."</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Die VPN-Einstellungen sind für diesen Nutzer nicht verfügbar."</string>
diff --git a/packages/SettingsLib/res/values-el/arrays.xml b/packages/SettingsLib/res/values-el/arrays.xml
index cc796fb..2672eec 100644
--- a/packages/SettingsLib/res/values-el/arrays.xml
+++ b/packages/SettingsLib/res/values-el/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Το πολύ 3 διαδικασίες"</item>
     <item msgid="7899496259191969307">"Το πολύ 4 διεργασίες"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Φόρτιση σε εξέλιξη"</item>
+    <item msgid="5220695614993094977">"MTP (Πρωτόκολλο μεταφοράς πολυμέσων)"</item>
+    <item msgid="2086000968159047375">"PTP (Πρωτόκολλο μεταφοράς εικόνων)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
+    <item msgid="1718924214939774352">"Πηγή ήχου"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 792b3d6..008491f 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Προσωπικό"</string>
     <string name="category_work" msgid="8699184680584175622">"Εργασία"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Επιλογές για προγραμματιστές"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Ενεργοποίηση επιλογών για προγραμματιστές"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Ορισμός επιλογών για ανάπτυξη εφαρμογής"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Οι επιλογές για προγραμματιστές δεν είναι διαθέσιμες για αυτόν το χρήστη"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Οι ρυθμίσεις VPN δεν είναι διαθέσιμες γι\' αυτόν το χρήστη"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/arrays.xml b/packages/SettingsLib/res/values-es-rUS/arrays.xml
index b92b598..52992d5 100644
--- a/packages/SettingsLib/res/values-es-rUS/arrays.xml
+++ b/packages/SettingsLib/res/values-es-rUS/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Máximo 3 procesos"</item>
     <item msgid="7899496259191969307">"Máximo 4 procesos"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"En carga"</item>
+    <item msgid="5220695614993094977">"Protocolo de transferencia multimedia (MTP)"</item>
+    <item msgid="2086000968159047375">"Protocolo de transferencia de imágenes (PTP)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
+    <item msgid="1718924214939774352">"Fuente de audio"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 6085c08..2612943 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Personal"</string>
     <string name="category_work" msgid="8699184680584175622">"Trabajo"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Opciones del programador"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Activar opciones para programador"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Establecer opciones para desarrollar aplicaciones"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Las opciones de programador no están disponibles para este usuario."</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"La configuración de la red VPN no está disponible para este usuario."</string>
diff --git a/packages/SettingsLib/res/values-et-rEE/arrays.xml b/packages/SettingsLib/res/values-et-rEE/arrays.xml
index c88ef1c..5bf13bb 100644
--- a/packages/SettingsLib/res/values-et-rEE/arrays.xml
+++ b/packages/SettingsLib/res/values-et-rEE/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Maksimaalselt 3 protsessi"</item>
     <item msgid="7899496259191969307">"Maksimaalselt 4 protsessi"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Laadimine"</item>
+    <item msgid="5220695614993094977">"MTP (Media Transfer Protocol)"</item>
+    <item msgid="2086000968159047375">"PTP (Picture Transfer Protocol)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
+    <item msgid="1718924214939774352">"Heliallikas"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-et-rEE/strings.xml b/packages/SettingsLib/res/values-et-rEE/strings.xml
index 79d3152..5fb55eb 100644
--- a/packages/SettingsLib/res/values-et-rEE/strings.xml
+++ b/packages/SettingsLib/res/values-et-rEE/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Isiklik"</string>
     <string name="category_work" msgid="8699184680584175622">"Töö"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Arendaja valikud"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Arendaja valikute lubamine"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Rakenduse arenduse valikute määramine"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Arendaja valikud pole selle kasutaja jaoks saadaval"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"VPN-i seaded pole selle kasutaja jaoks saadaval"</string>
diff --git a/packages/SettingsLib/res/values-fa/arrays.xml b/packages/SettingsLib/res/values-fa/arrays.xml
index 1507cda..d75280b 100644
--- a/packages/SettingsLib/res/values-fa/arrays.xml
+++ b/packages/SettingsLib/res/values-fa/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"حداکثر 3 پردازش"</item>
     <item msgid="7899496259191969307">"حداکثر 4 پردازش"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"در حال شارژ شدن"</item>
+    <item msgid="5220695614993094977">"‏MTP (پروتکل انتقال رسانه)"</item>
+    <item msgid="2086000968159047375">"‏PTP (پروتکل انتقال تصویر)"</item>
+    <item msgid="7398830860950841822">"‏RNDIS (اترنت USB)"</item>
+    <item msgid="1718924214939774352">"منبع صوتی"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index bce7b2a..2551ba5 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"شخصی"</string>
     <string name="category_work" msgid="8699184680584175622">"محل کار"</string>
     <string name="development_settings_title" msgid="215179176067683667">"گزینه‌های برنامه‌نویسان"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"فعال کردن گزینه‌های برنامه‌نویس"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"تنظیم گزینه‌های مربوط به طراحی برنامه"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"گزینه‌های برنامه‌نویس برای این کاربر موجود نیست"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"‏تنظیمات VPN برای این کاربر در دسترس نیست"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/arrays.xml b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
index 1772976..714dbe4 100644
--- a/packages/SettingsLib/res/values-fr-rCA/arrays.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Trois processus maximum"</item>
     <item msgid="7899496259191969307">"Quatre processus maximum"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Charge en cours"</item>
+    <item msgid="5220695614993094977">"MTP (Media Transfer Protocol, protocole de transfert de fichiers multimédias)"</item>
+    <item msgid="2086000968159047375">"PTP (Picture Transfer Protocol, protocole de transfert d\'images)"</item>
+    <item msgid="7398830860950841822">"RNDIS (Ethernet USB)"</item>
+    <item msgid="1718924214939774352">"Source audio"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 9652e52..f2c79de 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Personnel"</string>
     <string name="category_work" msgid="8699184680584175622">"Travail"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Options pour les développeurs"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Activer les options pour les développeurs"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Définir les options pour le développement de l\'application"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Les options proposées aux développeurs ne sont pas disponibles pour cet utilisateur."</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Les paramètres de RPV ne sont pas disponibles pour cet utilisateur"</string>
diff --git a/packages/SettingsLib/res/values-fr/arrays.xml b/packages/SettingsLib/res/values-fr/arrays.xml
index 9535963..a8bed69 100644
--- a/packages/SettingsLib/res/values-fr/arrays.xml
+++ b/packages/SettingsLib/res/values-fr/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Trois processus maximum"</item>
     <item msgid="7899496259191969307">"Quatre processus maximum"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"En charge"</item>
+    <item msgid="5220695614993094977">"MTP (Media Transfer Protocol)"</item>
+    <item msgid="2086000968159047375">"PTP (Picture Transfer Protocol)"</item>
+    <item msgid="7398830860950841822">"RNDIS (Ethernet USB)"</item>
+    <item msgid="1718924214939774352">"Source audio"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 8056f28..95e8804 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Personnel"</string>
     <string name="category_work" msgid="8699184680584175622">"Professionnel"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Options pour les développeurs"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Activer les options pour les développeurs"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Définir les options pour le développement de l\'application"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Les options proposées aux développeurs ne sont pas disponibles pour cet utilisateur."</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Les paramètres VPN ne sont pas disponibles pour cet utilisateur."</string>
diff --git a/packages/SettingsLib/res/values-gl-rES/arrays.xml b/packages/SettingsLib/res/values-gl-rES/arrays.xml
index 4f0840d..606e6f6 100644
--- a/packages/SettingsLib/res/values-gl-rES/arrays.xml
+++ b/packages/SettingsLib/res/values-gl-rES/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Como moito 3 procesos"</item>
     <item msgid="7899496259191969307">"Como moito 4 procesos"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Cargando"</item>
+    <item msgid="5220695614993094977">"MTP (protocolo de transferencia multimedia)"</item>
+    <item msgid="2086000968159047375">"PTP (protocolo de transferencia de imaxes)"</item>
+    <item msgid="7398830860950841822">"RNDIS (Ethernet USB)"</item>
+    <item msgid="1718924214939774352">"Fonte de audio"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-gl-rES/strings.xml b/packages/SettingsLib/res/values-gl-rES/strings.xml
index bf9920d..d7ef503 100644
--- a/packages/SettingsLib/res/values-gl-rES/strings.xml
+++ b/packages/SettingsLib/res/values-gl-rES/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Persoal"</string>
     <string name="category_work" msgid="8699184680584175622">"Traballo"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Opcións de programador"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Activar opcións de programador"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Definir as opcións de desenvolvemento de aplicacións"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"As opcións do programador non están dispoñibles para este usuario"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"A configuración da VPN non está dispoñible para este usuario"</string>
diff --git a/packages/SettingsLib/res/values-hr/arrays.xml b/packages/SettingsLib/res/values-hr/arrays.xml
index 250e26a..d51f82d 100644
--- a/packages/SettingsLib/res/values-hr/arrays.xml
+++ b/packages/SettingsLib/res/values-hr/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Najviše 3 procesa"</item>
     <item msgid="7899496259191969307">"Najviše 4 procesa"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Punjenje"</item>
+    <item msgid="5220695614993094977">"MTP (protokol za prijenos medija)"</item>
+    <item msgid="2086000968159047375">"PTP (protokol za prijenos fotografija)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB ethernet)"</item>
+    <item msgid="1718924214939774352">"Audioizvor"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index b11568f..f8434eb 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Osobno"</string>
     <string name="category_work" msgid="8699184680584175622">"Posao"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Opcije za razvojne programere"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Omogući opcije za razvojne programere"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Postavljanje opcija za razvoj aplikacije"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Opcije razvojnih programera nisu dostupne za ovog korisnika"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Postavke VPN-a nisu dostupne ovom korisniku"</string>
diff --git a/packages/SettingsLib/res/values-hy-rAM/arrays.xml b/packages/SettingsLib/res/values-hy-rAM/arrays.xml
index b320414..41143de 100644
--- a/packages/SettingsLib/res/values-hy-rAM/arrays.xml
+++ b/packages/SettingsLib/res/values-hy-rAM/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Առավելագույնը 3  գործընթաց"</item>
     <item msgid="7899496259191969307">"Ամենաշատը 4 գործընթաց"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Լիցքավորում"</item>
+    <item msgid="5220695614993094977">"MTP (Մեդիա ֆայլերի փոխանցման հաղորդակարգ)"</item>
+    <item msgid="2086000968159047375">"PTP (Նկարների փոխանցման հաղորդակարգ)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
+    <item msgid="1718924214939774352">"Ձայնի աղբյուրը"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-hy-rAM/strings.xml b/packages/SettingsLib/res/values-hy-rAM/strings.xml
index c038511..a2b901a 100644
--- a/packages/SettingsLib/res/values-hy-rAM/strings.xml
+++ b/packages/SettingsLib/res/values-hy-rAM/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Անձնական"</string>
     <string name="category_work" msgid="8699184680584175622">"Աշխատանքային"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Ծրագրավորման ընտրանքներ"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Միացնել մշակողի ընտրանքները"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Կարգավորել ընտրանքները ծրագրի ծրագրավորման համար"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Ծրագրավորման ընտրանքներն այլևս հասանելի չեն այս օգտվողի համար"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"VPN-ի կարգավորումները հասանելի չեն այս օգտվողին"</string>
diff --git a/packages/SettingsLib/res/values-is-rIS/arrays.xml b/packages/SettingsLib/res/values-is-rIS/arrays.xml
index 3cb853d..bbc7aec6 100644
--- a/packages/SettingsLib/res/values-is-rIS/arrays.xml
+++ b/packages/SettingsLib/res/values-is-rIS/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Að hámarki 3 vinnslur"</item>
     <item msgid="7899496259191969307">"Að hámarki 4 vinnslur"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Í hleðslu"</item>
+    <item msgid="5220695614993094977">"MTP (Media Transfer Protocol)"</item>
+    <item msgid="2086000968159047375">"PTP (Picture Transfer Protocol)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
+    <item msgid="1718924214939774352">"Audio Source"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-is-rIS/strings.xml b/packages/SettingsLib/res/values-is-rIS/strings.xml
index f601d3e..4139e6e 100644
--- a/packages/SettingsLib/res/values-is-rIS/strings.xml
+++ b/packages/SettingsLib/res/values-is-rIS/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Persónulegt"</string>
     <string name="category_work" msgid="8699184680584175622">"Vinna"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Forritunarkostir"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Virkja valkosti þróunaraðila"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Stilla valkosti fyrir forritaþróun"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Valkostir þróunaraðila eru ekki í boði fyrir þennan notanda"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"VPN-stillingar eru ekki í boði fyrir þennan notanda"</string>
diff --git a/packages/SettingsLib/res/values-ja/arrays.xml b/packages/SettingsLib/res/values-ja/arrays.xml
index 451c57f..6307a10 100644
--- a/packages/SettingsLib/res/values-ja/arrays.xml
+++ b/packages/SettingsLib/res/values-ja/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"プロセスの上限: 3"</item>
     <item msgid="7899496259191969307">"プロセスの上限: 4"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"充電しています"</item>
+    <item msgid="5220695614993094977">"MTP(Media Transfer Protocol)"</item>
+    <item msgid="2086000968159047375">"PTP(Picture Transfer Protocol)"</item>
+    <item msgid="7398830860950841822">"RNDIS(USBイーサネット)"</item>
+    <item msgid="1718924214939774352">"オーディオソース"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 5a8c028..4c043ac 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"個人用"</string>
     <string name="category_work" msgid="8699184680584175622">"仕事用"</string>
     <string name="development_settings_title" msgid="215179176067683667">"開発者向けオプション"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"開発者向けオプションの有効化"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"アプリ開発オプションを設定する"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"デベロッパー向けオプションはこのユーザーには表示されません"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"このユーザーはVPN設定を利用できません。"</string>
diff --git a/packages/SettingsLib/res/values-ka-rGE/arrays.xml b/packages/SettingsLib/res/values-ka-rGE/arrays.xml
index 14f0d1a..ac627a2 100644
--- a/packages/SettingsLib/res/values-ka-rGE/arrays.xml
+++ b/packages/SettingsLib/res/values-ka-rGE/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"არა უმეტეს 3 პროცესისა"</item>
     <item msgid="7899496259191969307">"არაუმეტეს 4 პროცესისა"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"იტენება"</item>
+    <item msgid="5220695614993094977">"MTP (Media Transfer Protocol)"</item>
+    <item msgid="2086000968159047375">"PTP (Picture Transfer Protocol)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
+    <item msgid="1718924214939774352">"აუდიო წყარo"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ka-rGE/strings.xml b/packages/SettingsLib/res/values-ka-rGE/strings.xml
index f3bf04d..1ea79bf 100644
--- a/packages/SettingsLib/res/values-ka-rGE/strings.xml
+++ b/packages/SettingsLib/res/values-ka-rGE/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"პირადი"</string>
     <string name="category_work" msgid="8699184680584175622">"სამსახური"</string>
     <string name="development_settings_title" msgid="215179176067683667">"პარამეტრები დეველოპერებისთვის"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"დეველოპერთა პარამეტრების ჩართვა"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"პარამეტრების დაყენება აპების დეველოპერებისთვის"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"ამ მომხმარებლისთვის დეველოპერის პარამეტრები არ არის ხელმისაწვდომი"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"VPN პარამეტრები ამ მომხმარებლისათვის მიუწვდომელია"</string>
diff --git a/packages/SettingsLib/res/values-ko/arrays.xml b/packages/SettingsLib/res/values-ko/arrays.xml
index 627abd4..a8d548f 100644
--- a/packages/SettingsLib/res/values-ko/arrays.xml
+++ b/packages/SettingsLib/res/values-ko/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"최대 3개 프로세스"</item>
     <item msgid="7899496259191969307">"최대 4개 프로세스"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"충전"</item>
+    <item msgid="5220695614993094977">"MTP(Media Transfer Protocol)"</item>
+    <item msgid="2086000968159047375">"PTP(Picture Transfer Protocol)"</item>
+    <item msgid="7398830860950841822">"RNDIS(USB 이더넷)"</item>
+    <item msgid="1718924214939774352">"오디오 소스"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 8f4b439..c4ab084 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"개인"</string>
     <string name="category_work" msgid="8699184680584175622">"직장"</string>
     <string name="development_settings_title" msgid="215179176067683667">"개발자 옵션"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"개발자 옵션 사용"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"앱 개발 옵션 설정"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"이 사용자는 개발자 옵션을 사용할 수 없습니다."</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"이 사용자는 VPN 설정을 수정할 수 없습니다."</string>
diff --git a/packages/SettingsLib/res/values-ky-rKG/arrays.xml b/packages/SettingsLib/res/values-ky-rKG/arrays.xml
index 97d4f2c..7ec569e 100644
--- a/packages/SettingsLib/res/values-ky-rKG/arrays.xml
+++ b/packages/SettingsLib/res/values-ky-rKG/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Эң көп дегенде 3 процесс"</item>
     <item msgid="7899496259191969307">"Эң көп дегенде 4 процесс"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Кубатталууда"</item>
+    <item msgid="5220695614993094977">"MTP (Медиа өткөрүүчү протокол)"</item>
+    <item msgid="2086000968159047375">"PTP (Сүрөт өткөрүүчү протокол)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
+    <item msgid="1718924214939774352">"Аудио булак"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ky-rKG/strings.xml b/packages/SettingsLib/res/values-ky-rKG/strings.xml
index 267cc61..43d9790 100644
--- a/packages/SettingsLib/res/values-ky-rKG/strings.xml
+++ b/packages/SettingsLib/res/values-ky-rKG/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Жеке"</string>
     <string name="category_work" msgid="8699184680584175622">"Жумуш"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Иштеп чыгуучунун параметрлери"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Иштеп чыгуучунун параметрлери иштетүү"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Колдонмо өндүрүү мүмкүнчүлүктөрүн орнотуу"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Бул колдонуучуга өнүктүүрүүчү мүмкүнчүлүктөрү берилген эмес."</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Бул колдонуучу VPN жөндөөлөрүн колдоно албайт"</string>
diff --git a/packages/SettingsLib/res/values-mk-rMK/arrays.xml b/packages/SettingsLib/res/values-mk-rMK/arrays.xml
index 260afdc..c97b577 100644
--- a/packages/SettingsLib/res/values-mk-rMK/arrays.xml
+++ b/packages/SettingsLib/res/values-mk-rMK/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Најмногу 3 процеси"</item>
     <item msgid="7899496259191969307">"Најмногу 4 процеси"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Се полни"</item>
+    <item msgid="5220695614993094977">"МТП (Протокол за трансфер на медиуми)"</item>
+    <item msgid="2086000968159047375">"ПТП (Протокол за трансфер на слика)"</item>
+    <item msgid="7398830860950841822">"РНДИС (УСБ за етернет)"</item>
+    <item msgid="1718924214939774352">"Аудиоизвор"</item>
+    <item msgid="8126315616613006284">"МИДИ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-mk-rMK/strings.xml b/packages/SettingsLib/res/values-mk-rMK/strings.xml
index 7705f34..f19b7b3 100644
--- a/packages/SettingsLib/res/values-mk-rMK/strings.xml
+++ b/packages/SettingsLib/res/values-mk-rMK/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Лични"</string>
     <string name="category_work" msgid="8699184680584175622">"Работа"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Опции на развивач"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Овозможете ги опциите за програмери"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Постави опции за развој на апликација"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Опциите на програмерот не се достапни за овој корисник"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Поставките за ВПН не се достапни за овој корисник"</string>
diff --git a/packages/SettingsLib/res/values-mn-rMN/arrays.xml b/packages/SettingsLib/res/values-mn-rMN/arrays.xml
index c869ff4..c4c6d28 100644
--- a/packages/SettingsLib/res/values-mn-rMN/arrays.xml
+++ b/packages/SettingsLib/res/values-mn-rMN/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Хамгийн ихдээ 3 процесс"</item>
     <item msgid="7899496259191969307">"Хамгийн ихдээ 4 процесс"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Цэнэглэж байна"</item>
+    <item msgid="5220695614993094977">"MTP (Медиа дамжуулах протокол)"</item>
+    <item msgid="2086000968159047375">"PTP (Зураг Дамжуулах Протокол)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
+    <item msgid="1718924214939774352">"Аудио эх сурвалж"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-mn-rMN/strings.xml b/packages/SettingsLib/res/values-mn-rMN/strings.xml
index ffbbec5..62e2c39 100644
--- a/packages/SettingsLib/res/values-mn-rMN/strings.xml
+++ b/packages/SettingsLib/res/values-mn-rMN/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Хувийн"</string>
     <string name="category_work" msgid="8699184680584175622">"Ажил"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Хөгжүүлэгчийн тохиргоо"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Хөгжүүлэгчийн сонголтыг идэвхжүүлэх"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Апп хөгжүүлэлтэд зориулсан сонголтуудыг тохируулах"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Энэ хэрэглэгч хөгжүүлэгчийн тохиргоог ашиглах боломжгүй"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Энэ хэрэглэгчид VPN тохиргоог ашиглах боломжгүй"</string>
diff --git a/packages/SettingsLib/res/values-ms-rMY/arrays.xml b/packages/SettingsLib/res/values-ms-rMY/arrays.xml
index d191075..320fa9b 100644
--- a/packages/SettingsLib/res/values-ms-rMY/arrays.xml
+++ b/packages/SettingsLib/res/values-ms-rMY/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Paling banyak 3 proses"</item>
     <item msgid="7899496259191969307">"Paling banyak 4 proses"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Mengecas"</item>
+    <item msgid="5220695614993094977">"MTP (Protokol Pindahan Media)"</item>
+    <item msgid="2086000968159047375">"PTP (Protokol Pindahan Gambar)"</item>
+    <item msgid="7398830860950841822">"RNDIS (Ethernet USB)"</item>
+    <item msgid="1718924214939774352">"Sumber Audio"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ms-rMY/strings.xml b/packages/SettingsLib/res/values-ms-rMY/strings.xml
index 40ba9a6..babbefa 100644
--- a/packages/SettingsLib/res/values-ms-rMY/strings.xml
+++ b/packages/SettingsLib/res/values-ms-rMY/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Peribadi"</string>
     <string name="category_work" msgid="8699184680584175622">"Tempat Kerja"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Pilihan pembangun"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Dayakan pilihan pembangun"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Tetapkan pilihan untuk pembangunan aplikasi"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Pilihan Pemaju tidak tersedia untuk pengguna ini"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Tetapan VPN tidak tersedia untuk pengguna ini"</string>
diff --git a/packages/SettingsLib/res/values-nb/arrays.xml b/packages/SettingsLib/res/values-nb/arrays.xml
index acc3570..0877f5c 100644
--- a/packages/SettingsLib/res/values-nb/arrays.xml
+++ b/packages/SettingsLib/res/values-nb/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Maksimalt 3 prosesser"</item>
     <item msgid="7899496259191969307">"Maksimalt 4 prosesser"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Lader"</item>
+    <item msgid="5220695614993094977">"MTP (Media Transfer Protocol)"</item>
+    <item msgid="2086000968159047375">"PTP (Picture Transfer Protocol)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
+    <item msgid="1718924214939774352">"Lydkilde"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 36ef78b..2b461e7 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Personlig"</string>
     <string name="category_work" msgid="8699184680584175622">"Jobb"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Utvikleralternativer"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Slå på utvikleralternativer"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Angi alternativer for apputvikling"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Utvikleralternativene er ikke tilgjengelige for denne brukeren"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Innstillingene for VPN er ikke tilgjengelig for denne brukeren"</string>
diff --git a/packages/SettingsLib/res/values-nl/arrays.xml b/packages/SettingsLib/res/values-nl/arrays.xml
index a119f42..7f76bba 100644
--- a/packages/SettingsLib/res/values-nl/arrays.xml
+++ b/packages/SettingsLib/res/values-nl/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Maximaal 3 processen"</item>
     <item msgid="7899496259191969307">"Maximaal 4 processen"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Opladen"</item>
+    <item msgid="5220695614993094977">"MTP (Media Transfer Protocol)"</item>
+    <item msgid="2086000968159047375">"PTP (Picture Transfer Protocol)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB-Ethernet)"</item>
+    <item msgid="1718924214939774352">"Audiobron"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index bd5c981..49242f9 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Persoonlijk"</string>
     <string name="category_work" msgid="8699184680584175622">"Werk"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Opties voor ontwikkelaars"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Opties voor ontwikkelaars inschakelen"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Opties instellen voor appontwikkeling"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Ontwikkelaarsopties zijn niet beschikbaar voor deze gebruiker"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Instellingen voor VPN zijn niet beschikbaar voor deze gebruiker"</string>
diff --git a/packages/SettingsLib/res/values-pl/arrays.xml b/packages/SettingsLib/res/values-pl/arrays.xml
index b480854..8df26cd 100644
--- a/packages/SettingsLib/res/values-pl/arrays.xml
+++ b/packages/SettingsLib/res/values-pl/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Maksymalnie 3 procesy"</item>
     <item msgid="7899496259191969307">"Maksymalnie 4 procesy"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Ładowanie"</item>
+    <item msgid="5220695614993094977">"MTP (Media Transfer Protocol)"</item>
+    <item msgid="2086000968159047375">"PTP (Picture Transfer Protocol)"</item>
+    <item msgid="7398830860950841822">"RNDIS (Ethernet przez USB)"</item>
+    <item msgid="1718924214939774352">"Źródło dźwięku"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 8b7dd3f..2efb5c9 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Osobiste"</string>
     <string name="category_work" msgid="8699184680584175622">"Praca"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Opcje programistyczne"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Włącz opcje dla programistów"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Ustaw opcje związane z programowaniem aplikacji."</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Opcje programisty są niedostępne dla tego użytkownika"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Ustawienia VPN są niedostępne dla tego użytkownika"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/arrays.xml b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
index f12841c..693430c 100644
--- a/packages/SettingsLib/res/values-pt-rPT/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"No máximo, 3 processos"</item>
     <item msgid="7899496259191969307">"No máximo, 4 processos"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Carregamento"</item>
+    <item msgid="5220695614993094977">"MTP (Protocolo de transferência de multimédia)"</item>
+    <item msgid="2086000968159047375">"PTP (Protocolo de transferência de imagens)"</item>
+    <item msgid="7398830860950841822">"RNDIS (Ethernet USB)"</item>
+    <item msgid="1718924214939774352">"Fonte de áudio"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 156a600..2a8402e 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Pessoal"</string>
     <string name="category_work" msgid="8699184680584175622">"Trabalho"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Opções de programador"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Ativar as opções de programador"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Definir opções de desenvolvimento da aplicação"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"As opções de programador não estão disponíveis para este utilizador"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"As definições de VPN não estão disponíveis para este utilizador"</string>
diff --git a/packages/SettingsLib/res/values-ro/arrays.xml b/packages/SettingsLib/res/values-ro/arrays.xml
index cae6812..f75154f 100644
--- a/packages/SettingsLib/res/values-ro/arrays.xml
+++ b/packages/SettingsLib/res/values-ro/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Cel mult 3 procese"</item>
     <item msgid="7899496259191969307">"Cel mult 4 procese"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Încărcare"</item>
+    <item msgid="5220695614993094977">"MTP (Media Transfer Protocol)"</item>
+    <item msgid="2086000968159047375">"PTP (Picture Transfer Protocol)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
+    <item msgid="1718924214939774352">"Sursă audio"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index b34813a..c45ede5 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Personal"</string>
     <string name="category_work" msgid="8699184680584175622">"Serviciu"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Opțiuni dezvoltator"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Activați opțiunile pentru dezvoltatori"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Setați opțiuni pentru dezvoltarea aplicației"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Opțiunile de dezvoltator nu sunt disponibile pentru acest utilizator"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Setările VPN nu sunt disponibile pentru acest utilizator"</string>
diff --git a/packages/SettingsLib/res/values-sl/arrays.xml b/packages/SettingsLib/res/values-sl/arrays.xml
index 9c3338c..253f113 100644
--- a/packages/SettingsLib/res/values-sl/arrays.xml
+++ b/packages/SettingsLib/res/values-sl/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Največ 3 postopki"</item>
     <item msgid="7899496259191969307">"Največ 4 postopki"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Polnjenje"</item>
+    <item msgid="5220695614993094977">"MTP (protokol za prenos predstavnosti)"</item>
+    <item msgid="2086000968159047375">"PTP (protokol za prenos slik)"</item>
+    <item msgid="7398830860950841822">"RNDIS (Ethernet USB)"</item>
+    <item msgid="1718924214939774352">"Vir zvoka"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 6a9f863..04918e0 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Osebno"</string>
     <string name="category_work" msgid="8699184680584175622">"Služba"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Možnosti za razvijalce"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Omogočanje možnosti za razvijalce"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Nastavi možnosti za razvoj aplikacij"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Možnosti razvijalca niso na voljo za tega uporabnika"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Nastavitve VPN niso na voljo za tega uporabnika"</string>
diff --git a/packages/SettingsLib/res/values-sq-rAL/arrays.xml b/packages/SettingsLib/res/values-sq-rAL/arrays.xml
index 2ed253f..7473f16 100644
--- a/packages/SettingsLib/res/values-sq-rAL/arrays.xml
+++ b/packages/SettingsLib/res/values-sq-rAL/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Maksimumi 3 procese"</item>
     <item msgid="7899496259191969307">"Maksimumi 4 procese"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Po ngarkohet"</item>
+    <item msgid="5220695614993094977">"MTP (Protokolli i Transferimit të Medias)"</item>
+    <item msgid="2086000968159047375">"PTP (Protokolli i Transferimit të Fotografive)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB Eternet)"</item>
+    <item msgid="1718924214939774352">"Burimi i audios"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sq-rAL/strings.xml b/packages/SettingsLib/res/values-sq-rAL/strings.xml
index ced2013..3bc769c 100644
--- a/packages/SettingsLib/res/values-sq-rAL/strings.xml
+++ b/packages/SettingsLib/res/values-sq-rAL/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Personale"</string>
     <string name="category_work" msgid="8699184680584175622">"Punë"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Opsionet e zhvilluesit"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Aktivizo opsionet e zhvilluesit"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Cakto opsionet për zhvillimin e aplikacionit"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Opsionet e programuesit nuk mundësohen për këtë përdorues"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Cilësimet e VPN-së nuk ofrohen për këtë përdorues"</string>
diff --git a/packages/SettingsLib/res/values-sr/arrays.xml b/packages/SettingsLib/res/values-sr/arrays.xml
index 39583aa..cd44e15 100644
--- a/packages/SettingsLib/res/values-sr/arrays.xml
+++ b/packages/SettingsLib/res/values-sr/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Највише три процеса"</item>
     <item msgid="7899496259191969307">"Највише четири процеса"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Пуњење"</item>
+    <item msgid="5220695614993094977">"MTP (протокол за трансфер медија)"</item>
+    <item msgid="2086000968159047375">"PTP (протокол за пренос слика)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB етернет)"</item>
+    <item msgid="1718924214939774352">"Извор звука"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index a2be0e4..036622f 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Лично"</string>
     <string name="category_work" msgid="8699184680584175622">"Посао"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Опције за програмера"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Омогући опције за програмера"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Подешавање опција за програмирање апликације"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Опције за програмере нису доступне за овог корисника"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Подешавања VPN-а нису доступна за овог корисника"</string>
diff --git a/packages/SettingsLib/res/values-sv/arrays.xml b/packages/SettingsLib/res/values-sv/arrays.xml
index e77ec0a..54537f4 100644
--- a/packages/SettingsLib/res/values-sv/arrays.xml
+++ b/packages/SettingsLib/res/values-sv/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Högst 3 processer"</item>
     <item msgid="7899496259191969307">"Högst 4 processer"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Laddar"</item>
+    <item msgid="5220695614993094977">"MTP (Media Transfer Protocol)"</item>
+    <item msgid="2086000968159047375">"PTP (Picture Transfer Protocol)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB-ethernet)"</item>
+    <item msgid="1718924214939774352">"Ljudkälla"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 9fb6f37..2f95b06 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Personligt"</string>
     <string name="category_work" msgid="8699184680584175622">"Arbetet"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Utvecklaralternativ"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Aktivera utvecklaralternativ"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Ange alternativ för apputveckling"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Utvecklaralternativ är inte tillgängliga för den här användaren"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"VPN-inställningarna är inte tillgängliga för den här användaren"</string>
diff --git a/packages/SettingsLib/res/values-ta-rIN/arrays.xml b/packages/SettingsLib/res/values-ta-rIN/arrays.xml
index 978a729..ad42159 100644
--- a/packages/SettingsLib/res/values-ta-rIN/arrays.xml
+++ b/packages/SettingsLib/res/values-ta-rIN/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"அதிகபட்சமாக 3 செயல்முறைகள்"</item>
     <item msgid="7899496259191969307">"அதிகபட்சமாக 4 செயல்முறைகள்"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"சார்ஜ் ஏறுகிறது"</item>
+    <item msgid="5220695614993094977">"MTP (மீடியா பரிமாற்ற நெறிமுறை)"</item>
+    <item msgid="2086000968159047375">"PTP (படப் பரிமாற்ற நெறிமுறை)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB ஈத்தர்நெட்)"</item>
+    <item msgid="1718924214939774352">"ஆடியோ மூலம்"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ta-rIN/strings.xml b/packages/SettingsLib/res/values-ta-rIN/strings.xml
index 2d35f7b..f4fee1f 100644
--- a/packages/SettingsLib/res/values-ta-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-ta-rIN/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"தனிப்பட்டவை"</string>
     <string name="category_work" msgid="8699184680584175622">"பணியிடம்"</string>
     <string name="development_settings_title" msgid="215179176067683667">"டெவெலப்பர் விருப்பங்கள்"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"டெவெலப்பர் விருப்பங்களை இயக்கு"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"பயன்பாட்டின் மேம்பாட்டிற்காக விருப்பங்களை அமை"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"இவருக்கு, டெவெலப்பர் விருப்பங்கள் இல்லை"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"இவரால் VPN அமைப்புகளை மாற்ற முடியாது"</string>
diff --git a/packages/SettingsLib/res/values-th/arrays.xml b/packages/SettingsLib/res/values-th/arrays.xml
index c65988e..43d2739 100644
--- a/packages/SettingsLib/res/values-th/arrays.xml
+++ b/packages/SettingsLib/res/values-th/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"มากที่สุด 3 กระบวนการ"</item>
     <item msgid="7899496259191969307">"มากที่สุด 4 กระบวนการ"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"การชาร์จ"</item>
+    <item msgid="5220695614993094977">"MTP (โปรโตคอลการโอนสื่อ)"</item>
+    <item msgid="2086000968159047375">"PTP (โปรโตคอลการโอนรูปภาพ)"</item>
+    <item msgid="7398830860950841822">"RNDIS (อีเทอร์เน็ต USB)"</item>
+    <item msgid="1718924214939774352">"แหล่งที่มาของเสียง"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 30bed98..c91bb42 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"ส่วนตัว"</string>
     <string name="category_work" msgid="8699184680584175622">"ที่ทำงาน"</string>
     <string name="development_settings_title" msgid="215179176067683667">"สำหรับนักพัฒนาซอฟต์แวร์"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"เปิดใช้ตัวเลือกสำหรับนักพัฒนาซอฟต์แวร์"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"ตั้งค่าตัวเลือกสำหรับการพัฒนาแอปพลิเคชัน"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"ตัวเลือกสำหรับนักพัฒนาซอฟต์แวร์ไม่สามารถใช้ได้สำหรับผู้ใช้นี้"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"การตั้งค่า VPN ไม่สามารถใช้ได้สำหรับผู้ใช้รายนี้"</string>
diff --git a/packages/SettingsLib/res/values-tl/arrays.xml b/packages/SettingsLib/res/values-tl/arrays.xml
index 571560b..c7cf6d2 100644
--- a/packages/SettingsLib/res/values-tl/arrays.xml
+++ b/packages/SettingsLib/res/values-tl/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"3 proseso sa pinakamarami"</item>
     <item msgid="7899496259191969307">"4 na proseso sa pinakamarami"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Nagcha-charge"</item>
+    <item msgid="5220695614993094977">"MTP (Media Transfer Protocol)"</item>
+    <item msgid="2086000968159047375">"PTP (Picture Transfer Protocol)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
+    <item msgid="1718924214939774352">"Pinagmulan ng Audio"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 63d1c6b..a389feb 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Personal"</string>
     <string name="category_work" msgid="8699184680584175622">"Trabaho"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Mga opsyon ng developer"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"I-enable ang mga opsyon ng developer"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Magtakda ng mga pagpipilian para sa pagbuo ng app"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Hindi available ang mga pagpipilian ng developer para sa user na ito"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Hindi available ang mga setting ng VPN para sa user na ito"</string>
diff --git a/packages/SettingsLib/res/values-tr/arrays.xml b/packages/SettingsLib/res/values-tr/arrays.xml
index cecc51d..9326903 100644
--- a/packages/SettingsLib/res/values-tr/arrays.xml
+++ b/packages/SettingsLib/res/values-tr/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"En çok 3 işlem"</item>
     <item msgid="7899496259191969307">"En çok 4 işlem"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Şarj oluyor"</item>
+    <item msgid="5220695614993094977">"MTP (Medya Aktarım Protokolü)"</item>
+    <item msgid="2086000968159047375">"PTP (Resim Aktarım Protokolü)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
+    <item msgid="1718924214939774352">"Ses Kaynağı"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index dc6f188..48ed867 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Kişisel"</string>
     <string name="category_work" msgid="8699184680584175622">"İş"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Geliştirici seçenekleri"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Geliştirici seçeneklerini etkinleştir"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Uygulama geliştirme için seçenekleri ayarla"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Bu kullanıcı, geliştirici seçeneklerini kullanamaz"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"VPN ayarları bu kullanıcı için kullanılamıyor"</string>
diff --git a/packages/SettingsLib/res/values-uk/arrays.xml b/packages/SettingsLib/res/values-uk/arrays.xml
index 92bfe4f..6cccc8c 100644
--- a/packages/SettingsLib/res/values-uk/arrays.xml
+++ b/packages/SettingsLib/res/values-uk/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Не більше 3 процесів"</item>
     <item msgid="7899496259191969307">"Не більше 4 процесів"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Заряджається"</item>
+    <item msgid="5220695614993094977">"MTP (протокол передавання медіаданих)"</item>
+    <item msgid="2086000968159047375">"PTP (протокол передавання зображень)"</item>
+    <item msgid="7398830860950841822">"RNDIS (Ethernet через USB)"</item>
+    <item msgid="1718924214939774352">"Джерело аудіо"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index dfabfbd..5a0ddd0 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Особисте"</string>
     <string name="category_work" msgid="8699184680584175622">"Робота"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Параметри розробника"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Увімкнути параметри розробника"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Установити параметри для розробки програми"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Параметри розробника не доступні для цього користувача"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Цей користувач не може налаштовувати мережу VPN"</string>
diff --git a/packages/SettingsLib/res/values-ur-rPK/arrays.xml b/packages/SettingsLib/res/values-ur-rPK/arrays.xml
index 228c214..80fb750 100644
--- a/packages/SettingsLib/res/values-ur-rPK/arrays.xml
+++ b/packages/SettingsLib/res/values-ur-rPK/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"زیادہ سے زیادہ 3 پروسیسز"</item>
     <item msgid="7899496259191969307">"زیادہ سے زیادہ 4 پروسیسز"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"چارجنگ"</item>
+    <item msgid="5220695614993094977">"‏MTP (میڈیا کی منتقلی کا پروٹوکول)"</item>
+    <item msgid="2086000968159047375">"‏PTP (تصویر کی منتقلی کا پروٹوکول)"</item>
+    <item msgid="7398830860950841822">"‏RNDIS ‏(USB ایتھرنیٹ)‎"</item>
+    <item msgid="1718924214939774352">"آڈیو ماخذ"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-ur-rPK/strings.xml b/packages/SettingsLib/res/values-ur-rPK/strings.xml
index c71898f..3f6563b 100644
--- a/packages/SettingsLib/res/values-ur-rPK/strings.xml
+++ b/packages/SettingsLib/res/values-ur-rPK/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"ذاتی"</string>
     <string name="category_work" msgid="8699184680584175622">"دفتر"</string>
     <string name="development_settings_title" msgid="215179176067683667">"ڈویلپر کے اختیارات"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"ڈیولپر کے اختیارات فعال کریں"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"ایپ ڈویلپمنٹ کیلئے اختیارات سیٹ کریں"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"اس صارف کیلئے ڈیولپر کے اختیارات دستیاب نہیں ہیں"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"‏VPN ترتیبات اس صارف کیلئے دستیاب نہیں ہیں"</string>
diff --git a/packages/SettingsLib/res/values-uz-rUZ/arrays.xml b/packages/SettingsLib/res/values-uz-rUZ/arrays.xml
index b05a818..a84c5d5 100644
--- a/packages/SettingsLib/res/values-uz-rUZ/arrays.xml
+++ b/packages/SettingsLib/res/values-uz-rUZ/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"Ko‘pi bilan 3 ta jarayon"</item>
     <item msgid="7899496259191969307">"Ko‘pi bilan 4 ta jarayon"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"Quvvat olmoqda"</item>
+    <item msgid="5220695614993094977">"MTP (media fayllarni o‘tkazish protokoli)"</item>
+    <item msgid="2086000968159047375">"PTP (rasmlarni o‘tkazish protokoli)"</item>
+    <item msgid="7398830860950841822">"RNDIS (USB Ethernet)"</item>
+    <item msgid="1718924214939774352">"Audio manbasi"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-uz-rUZ/strings.xml b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
index d50a2c0..82e8dc6 100644
--- a/packages/SettingsLib/res/values-uz-rUZ/strings.xml
+++ b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"Shaxsiy"</string>
     <string name="category_work" msgid="8699184680584175622">"Ish"</string>
     <string name="development_settings_title" msgid="215179176067683667">"Dasturchi sozlamalari"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"Dasturchi sozlamalarini yoqish"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"Ilova dasturlash moslamalari"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"Bu foydalanuvchiga dasturchi imkoniyatlari taqdim etilmagan"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"Ushbu foydalanuvchi uchun VPN sozlamalari mavjud emas"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/arrays.xml b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
index 05640f3..1378aaa 100644
--- a/packages/SettingsLib/res/values-zh-rCN/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
@@ -147,5 +147,12 @@
     <item msgid="836593137872605381">"不得超过3个进程"</item>
     <item msgid="7899496259191969307">"不得超过4个进程"</item>
   </string-array>
-    <!-- no translation found for usb_configuration_titles:0 (488237561639712799) -->
+  <string-array name="usb_configuration_titles">
+    <item msgid="488237561639712799">"充电"</item>
+    <item msgid="5220695614993094977">"MTP(媒体传输协议)"</item>
+    <item msgid="2086000968159047375">"PTP(图片传输协议)"</item>
+    <item msgid="7398830860950841822">"RNDIS(USB 以太网)"</item>
+    <item msgid="1718924214939774352">"音频来源"</item>
+    <item msgid="8126315616613006284">"MIDI"</item>
+  </string-array>
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 8cfd8be..886a7ce 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -136,8 +136,7 @@
     <string name="category_personal" msgid="1299663247844969448">"个人"</string>
     <string name="category_work" msgid="8699184680584175622">"工作"</string>
     <string name="development_settings_title" msgid="215179176067683667">"开发者选项"</string>
-    <!-- no translation found for development_settings_enable (542530994778109538) -->
-    <skip />
+    <string name="development_settings_enable" msgid="542530994778109538">"启用开发者选项"</string>
     <string name="development_settings_summary" msgid="1815795401632854041">"设置应用开发选项"</string>
     <string name="development_settings_not_available" msgid="4308569041701535607">"此用户无法使用开发者选项"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"此用户无权修改VPN设置"</string>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/NetworkPolicySerializer.java b/packages/SettingsProvider/src/com/android/providers/settings/NetworkPolicySerializer.java
new file mode 100644
index 0000000..4b87da4
--- /dev/null
+++ b/packages/SettingsProvider/src/com/android/providers/settings/NetworkPolicySerializer.java
@@ -0,0 +1,186 @@
+package com.android.providers.settings;
+
+import android.net.NetworkPolicy;
+import android.net.NetworkTemplate;
+import android.util.Log;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+ * Backup/Restore Serializer Class for android.net.NetworkPolicy
+ */
+public class NetworkPolicySerializer {
+    private static final boolean DEBUG = false;
+    private static final String TAG = "NetworkPolicySerializer";
+
+    private static final int NULL = 0;
+    private static final int NOT_NULL = 1;
+    /**
+     * Current Version of the Serializer.
+     */
+    private static int STATE_VERSION = 1;
+
+    /**
+     * Marshals an array of NetworkPolicy objects into a byte-array.
+     *
+     * @param policies - NetworkPolicies to be Marshaled
+     * @return byte array
+     */
+
+    public static byte[] marshalNetworkPolicies(NetworkPolicy policies[]) {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        if (policies != null && policies.length != 0) {
+            DataOutputStream out = new DataOutputStream(baos);
+            try {
+                out.writeInt(STATE_VERSION);
+                out.writeInt(policies.length);
+                for (NetworkPolicy policy : policies) {
+                    byte[] marshaledPolicy = marshalNetworkPolicy(policy);
+                    if (marshaledPolicy != null) {
+                        out.writeByte(NOT_NULL);
+                        out.writeInt(marshaledPolicy.length);
+                        out.write(marshaledPolicy);
+                    } else {
+                        out.writeByte(NULL);
+                    }
+                }
+            } catch (IOException ioe) {
+                Log.e(TAG, "Failed to Convert NetworkPolicies to byte array", ioe);
+                baos.reset();
+            }
+        }
+        return baos.toByteArray();
+    }
+
+    /**
+     * Unmarshals a byte array into an array of NetworkPolicy Objects
+     *
+     * @param data - marshaled NetworkPolicies Array
+     * @return NetworkPolicy[] array
+     */
+    public static NetworkPolicy[] unmarshalNetworkPolicies(byte[] data) {
+        if (data == null || data.length == 0) {
+            return new NetworkPolicy[0];
+        }
+        DataInputStream in = new DataInputStream(new ByteArrayInputStream(data));
+        try {
+            int version = in.readInt();
+            int length = in.readInt();
+            NetworkPolicy[] policies = new NetworkPolicy[length];
+            for (int i = 0; i < length; i++) {
+                byte isNull = in.readByte();
+                if (isNull == NULL) continue;
+                int byteLength = in.readInt();
+                byte[] policyData = new byte[byteLength];
+                in.read(policyData, 0, byteLength);
+                policies[i] = unmarshalNetworkPolicy(policyData);
+            }
+            return policies;
+        } catch (IOException ioe) {
+            Log.e(TAG, "Failed to Convert byte array to NetworkPolicies", ioe);
+            return new NetworkPolicy[0];
+        }
+    }
+
+    /**
+     * Marshals a NetworkPolicy object into a byte-array.
+     *
+     * @param networkPolicy - NetworkPolicy to be Marshaled
+     * @return byte array
+     */
+    public static byte[] marshalNetworkPolicy(NetworkPolicy networkPolicy) {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        if (networkPolicy != null) {
+            DataOutputStream out = new DataOutputStream(baos);
+            try {
+                out.writeInt(STATE_VERSION);
+                writeNetworkTemplate(out, networkPolicy.template);
+                out.writeInt(networkPolicy.cycleDay);
+                writeString(out, networkPolicy.cycleTimezone);
+                out.writeLong(networkPolicy.warningBytes);
+                out.writeLong(networkPolicy.limitBytes);
+                out.writeLong(networkPolicy.lastWarningSnooze);
+                out.writeLong(networkPolicy.lastLimitSnooze);
+                out.writeInt(networkPolicy.metered ? 1 : 0);
+                out.writeInt(networkPolicy.inferred ? 1 : 0);
+            } catch (IOException ioe) {
+                Log.e(TAG, "Failed to Convert NetworkPolicy to byte array", ioe);
+                baos.reset();
+            }
+        }
+        return baos.toByteArray();
+    }
+
+    /**
+     * Unmarshals a byte array into a NetworkPolicy Object
+     *
+     * @param data - marshaled NetworkPolicy Object
+     * @return NetworkPolicy Object
+     */
+    public static NetworkPolicy unmarshalNetworkPolicy(byte[] data) {
+        if (data == null || data.length == 0) {
+            return null;
+        }
+        DataInputStream in = new DataInputStream(new ByteArrayInputStream(data));
+        try {
+            int version = in.readInt();
+            NetworkTemplate template = readNetworkTemplate(in, version);
+            int cycleDay = in.readInt();
+            String cycleTimeZone = readString(in, version);
+            long warningBytes = in.readLong();
+            long limitBytes = in.readLong();
+            long lastWarningSnooze = in.readLong();
+            long lastLimitSnooze = in.readLong();
+            boolean metered = in.readInt() == 1;
+            boolean inferred = in.readInt() == 1;
+            return new NetworkPolicy(template, cycleDay, cycleTimeZone, warningBytes, limitBytes,
+                    lastWarningSnooze, lastLimitSnooze, metered, inferred);
+        } catch (IOException ioe) {
+            Log.e(TAG, "Failed to Convert byte array to NetworkPolicy", ioe);
+            return null;
+        }
+    }
+
+    private static NetworkTemplate readNetworkTemplate(DataInputStream in, int version)
+            throws IOException {
+        byte isNull = in.readByte();
+        if (isNull == NULL) return null;
+        int matchRule = in.readInt();
+        String subscriberId = readString(in, version);
+        String networkId = readString(in, version);
+        return new NetworkTemplate(matchRule, subscriberId, networkId);
+    }
+
+    private static void writeNetworkTemplate(DataOutputStream out, NetworkTemplate template)
+            throws IOException {
+        if (template != null) {
+            out.writeByte(NOT_NULL);
+            out.writeInt(template.getMatchRule());
+            writeString(out, template.getSubscriberId());
+            writeString(out, template.getNetworkId());
+        } else {
+            out.writeByte(NULL);
+        }
+    }
+
+    private static String readString(DataInputStream in, int version) throws IOException {
+        byte isNull = in.readByte();
+        if (isNull == NOT_NULL) {
+            return in.readUTF();
+        }
+        return null;
+    }
+
+    private static void writeString(DataOutputStream out, String val) throws IOException {
+        if (val != null) {
+            out.writeByte(NOT_NULL);
+            out.writeUTF(val);
+        } else {
+            out.writeByte(NULL);
+        }
+    }
+}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 2e96f18..185a03f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -24,6 +24,7 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
+import android.net.NetworkPolicyManager;
 import android.net.Uri;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
@@ -81,10 +82,13 @@
     private static final String KEY_GLOBAL = "global";
     private static final String KEY_LOCALE = "locale";
     private static final String KEY_LOCK_SETTINGS = "lock_settings";
+    private static final String KEY_SOFTAP_CONFIG = "softap_config";
+    private static final String KEY_NET_POLICIES = "network_policies";
+
 
     // Versioning of the state file.  Increment this version
     // number any time the set of state items is altered.
-    private static final int STATE_VERSION = 4;
+    private static final int STATE_VERSION = 6;
 
     // Slots in the checksum array.  Never insert new items in the middle
     // of this array; new slots must be appended.
@@ -95,22 +99,28 @@
     private static final int STATE_WIFI_CONFIG     = 4;
     private static final int STATE_GLOBAL          = 5;
     private static final int STATE_LOCK_SETTINGS   = 6;
+    private static final int STATE_SOFTAP_CONFIG   = 7;
+    private static final int STATE_NET_POLICIES    = 8;
 
-    private static final int STATE_SIZE            = 7; // The current number of state items
+    private static final int STATE_SIZE            = 9; // The current number of state items
 
     // Number of entries in the checksum array at various version numbers
     private static final int STATE_SIZES[] = {
-        0,
-        4,              // version 1
-        5,              // version 2 added STATE_WIFI_CONFIG
-        6,              // version 3 added STATE_GLOBAL
-        STATE_SIZE      // version 4 added STATE_LOCK_SETTINGS
+            0,
+            4,              // version 1
+            5,              // version 2 added STATE_WIFI_CONFIG
+            6,              // version 3 added STATE_GLOBAL
+            7,              // version 4 added STATE_LOCK_SETTINGS
+            8,              // version 5 added STATE_SOFTAP_CONFIG
+            STATE_SIZE      // version 6 added STATE_NET_POLICIES
     };
 
     // Versioning of the 'full backup' format
     private static final int FULL_BACKUP_VERSION = 3;
     private static final int FULL_BACKUP_ADDED_GLOBAL = 2;  // added the "global" entry
     private static final int FULL_BACKUP_ADDED_LOCK_SETTINGS = 3; // added the "lock_settings" entry
+    private static final int FULL_BACKUP_ADDED_SOFTAP_CONF = 4; //added the "softap_config" entry
+    private static final int FULL_BACKUP_ADDED_NET_POLICIES = 5; //added the "network_policies" entry
 
     private static final int INTEGER_BYTE_COUNT = Integer.SIZE / Byte.SIZE;
 
@@ -119,8 +129,8 @@
     private static final String TAG = "SettingsBackupAgent";
 
     private static final String[] PROJECTION = {
-        Settings.NameValueTable.NAME,
-        Settings.NameValueTable.VALUE
+            Settings.NameValueTable.NAME,
+            Settings.NameValueTable.VALUE
     };
 
     private static final String FILE_WIFI_SUPPLICANT = "/data/misc/wifi/wpa_supplicant.conf";
@@ -396,7 +406,7 @@
 
     @Override
     public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
-            ParcelFileDescriptor newState) throws IOException {
+                         ParcelFileDescriptor newState) throws IOException {
 
         byte[] systemSettingsData = getSystemSettings();
         byte[] secureSettingsData = getSecureSettings();
@@ -405,26 +415,34 @@
         byte[] locale = mSettingsHelper.getLocaleData();
         byte[] wifiSupplicantData = getWifiSupplicant(FILE_WIFI_SUPPLICANT);
         byte[] wifiConfigData = getFileData(mWifiConfigFile);
+        byte[] softApConfigData = getSoftAPConfiguration();
+        byte[] netPoliciesData = getNetworkPolicies();
 
         long[] stateChecksums = readOldChecksums(oldState);
 
         stateChecksums[STATE_SYSTEM] =
-            writeIfChanged(stateChecksums[STATE_SYSTEM], KEY_SYSTEM, systemSettingsData, data);
+                writeIfChanged(stateChecksums[STATE_SYSTEM], KEY_SYSTEM, systemSettingsData, data);
         stateChecksums[STATE_SECURE] =
-            writeIfChanged(stateChecksums[STATE_SECURE], KEY_SECURE, secureSettingsData, data);
+                writeIfChanged(stateChecksums[STATE_SECURE], KEY_SECURE, secureSettingsData, data);
         stateChecksums[STATE_GLOBAL] =
-            writeIfChanged(stateChecksums[STATE_GLOBAL], KEY_GLOBAL, globalSettingsData, data);
+                writeIfChanged(stateChecksums[STATE_GLOBAL], KEY_GLOBAL, globalSettingsData, data);
         stateChecksums[STATE_LOCALE] =
-            writeIfChanged(stateChecksums[STATE_LOCALE], KEY_LOCALE, locale, data);
+                writeIfChanged(stateChecksums[STATE_LOCALE], KEY_LOCALE, locale, data);
         stateChecksums[STATE_WIFI_SUPPLICANT] =
-            writeIfChanged(stateChecksums[STATE_WIFI_SUPPLICANT], KEY_WIFI_SUPPLICANT,
-                    wifiSupplicantData, data);
+                writeIfChanged(stateChecksums[STATE_WIFI_SUPPLICANT], KEY_WIFI_SUPPLICANT,
+                        wifiSupplicantData, data);
         stateChecksums[STATE_WIFI_CONFIG] =
-            writeIfChanged(stateChecksums[STATE_WIFI_CONFIG], KEY_WIFI_CONFIG, wifiConfigData,
-                    data);
+                writeIfChanged(stateChecksums[STATE_WIFI_CONFIG], KEY_WIFI_CONFIG, wifiConfigData,
+                        data);
         stateChecksums[STATE_LOCK_SETTINGS] =
-            writeIfChanged(stateChecksums[STATE_LOCK_SETTINGS], KEY_LOCK_SETTINGS,
-                    lockSettingsData, data);
+                writeIfChanged(stateChecksums[STATE_LOCK_SETTINGS], KEY_LOCK_SETTINGS,
+                        lockSettingsData, data);
+        stateChecksums[STATE_SOFTAP_CONFIG] =
+                writeIfChanged(stateChecksums[STATE_SOFTAP_CONFIG], KEY_SOFTAP_CONFIG,
+                        softApConfigData, data);
+        stateChecksums[STATE_NET_POLICIES] =
+                writeIfChanged(stateChecksums[STATE_NET_POLICIES], KEY_NET_POLICIES,
+                        netPoliciesData, data);
 
         writeNewChecksums(stateChecksums, newState);
     }
@@ -504,7 +522,7 @@
                             restoredSupplicantData, restoredSupplicantData.length);
                     FileUtils.setPermissions(FILE_WIFI_SUPPLICANT,
                             FileUtils.S_IRUSR | FileUtils.S_IWUSR |
-                            FileUtils.S_IRGRP | FileUtils.S_IWGRP,
+                                    FileUtils.S_IRGRP | FileUtils.S_IWGRP,
                             Process.myUid(), Process.WIFI_UID);
                 }
                 if (restoredWifiConfigFile != null) {
@@ -533,7 +551,7 @@
 
     @Override
     public void onRestore(BackupDataInput data, int appVersionCode,
-            ParcelFileDescriptor newState) throws IOException {
+                          ParcelFileDescriptor newState) throws IOException {
 
         HashSet<String> movedToGlobal = new HashSet<String>();
         Settings.System.getMovedToGlobalSettings(movedToGlobal);
@@ -561,7 +579,15 @@
                 mWifiRestore.incorporateWifiConfigFile(data);
             } else if (KEY_LOCK_SETTINGS.equals(key)) {
                 restoreLockSettings(data);
-             } else {
+            } else if (KEY_SOFTAP_CONFIG.equals(key)){
+                byte[] softapData = new byte[size];
+                data.readEntityData(softapData, 0, size);
+                restoreSoftApConfiguration(softapData);
+            } else if (KEY_NET_POLICIES.equals(key)) {
+                byte[] netPoliciesData = new byte[size];
+                data.readEntityData(netPoliciesData, 0, size);
+                restoreNetworkPolicies(netPoliciesData);
+            } else {
                 data.skipEntityData();
             }
         }
@@ -589,6 +615,8 @@
         byte[] locale = mSettingsHelper.getLocaleData();
         byte[] wifiSupplicantData = getWifiSupplicant(FILE_WIFI_SUPPLICANT);
         byte[] wifiConfigData = getFileData(mWifiConfigFile);
+        byte[] softApConfigData = getSoftAPConfiguration();
+        byte[] netPoliciesData = getNetworkPolicies();
 
         // Write the data to the staging file, then emit that as our tarfile
         // representation of the backed-up settings.
@@ -623,6 +651,12 @@
             if (DEBUG_BACKUP) Log.d(TAG, lockSettingsData.length + " bytes of lock settings data");
             out.writeInt(lockSettingsData.length);
             out.write(lockSettingsData);
+            if (DEBUG_BACKUP) Log.d(TAG, softApConfigData.length + " bytes of softap config data");
+            out.writeInt(softApConfigData.length);
+            out.write(softApConfigData);
+            if (DEBUG_BACKUP) Log.d(TAG, netPoliciesData.length + " bytes of network policies data");
+            out.writeInt(netPoliciesData.length);
+            out.write(netPoliciesData);
 
             out.flush();    // also flushes downstream
 
@@ -635,7 +669,7 @@
 
     @Override
     public void onRestoreFile(ParcelFileDescriptor data, long size,
-            int type, String domain, String relpath, long mode, long mtime)
+                              int type, String domain, String relpath, long mode, long mtime)
             throws IOException {
         if (DEBUG_BACKUP) Log.d(TAG, "onRestoreFile() invoked");
         // Our data is actually a blob of flattened settings data identical to that
@@ -692,7 +726,7 @@
             restoreWifiSupplicant(FILE_WIFI_SUPPLICANT, buffer, nBytes);
             FileUtils.setPermissions(FILE_WIFI_SUPPLICANT,
                     FileUtils.S_IRUSR | FileUtils.S_IWUSR |
-                    FileUtils.S_IRGRP | FileUtils.S_IWGRP,
+                            FileUtils.S_IRGRP | FileUtils.S_IWGRP,
                     Process.myUid(), Process.WIFI_UID);
             // retain the previous WIFI state.
             enableWifi(retainedWifiState == WifiManager.WIFI_STATE_ENABLED ||
@@ -715,6 +749,26 @@
                 }
             }
 
+            if (version >= FULL_BACKUP_ADDED_SOFTAP_CONF){
+                nBytes = in.readInt();
+                if (DEBUG_BACKUP) Log.d(TAG, nBytes + " bytes of softap config data");
+                if (nBytes > buffer.length) buffer = new byte[nBytes];
+                if (nBytes > 0) {
+                    in.readFully(buffer, 0, nBytes);
+                    restoreSoftApConfiguration(buffer);
+                }
+            }
+
+            if (version >= FULL_BACKUP_ADDED_NET_POLICIES){
+                nBytes = in.readInt();
+                if (DEBUG_BACKUP) Log.d(TAG, nBytes + " bytes of network policies data");
+                if (nBytes > buffer.length) buffer = new byte[nBytes];
+                if (nBytes > 0) {
+                    in.readFully(buffer, 0, nBytes);
+                    restoreNetworkPolicies(buffer);
+                }
+            }
+
             if (DEBUG_BACKUP) Log.d(TAG, "Full restore complete.");
         } else {
             data.close();
@@ -754,7 +808,7 @@
     }
 
     private long writeIfChanged(long oldChecksum, String key, byte[] data,
-            BackupDataOutput output) {
+                                BackupDataOutput output) {
         CRC32 checkSummer = new CRC32();
         checkSummer.update(data);
         long newChecksum = checkSummer.getValue();
@@ -829,7 +883,7 @@
     }
 
     private void restoreSettings(BackupDataInput data, Uri contentUri,
-            HashSet<String> movedToGlobal) {
+                                 HashSet<String> movedToGlobal) {
         byte[] settings = new byte[data.getDataSize()];
         try {
             data.readEntityData(settings, 0, settings.length);
@@ -841,7 +895,7 @@
     }
 
     private void restoreSettings(byte[] settings, int bytes, Uri contentUri,
-            HashSet<String> movedToGlobal) {
+                                 HashSet<String> movedToGlobal) {
         if (DEBUG) {
             Log.i(TAG, "restoreSettings: " + contentUri);
         }
@@ -1160,6 +1214,30 @@
         }
     }
 
+    private byte[] getSoftAPConfiguration(){
+        WifiManager wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
+        return WiFiConfigurationSerializer.marshalWifiConfig(wifiManager.getWifiApConfiguration());
+    }
+
+    private void restoreSoftApConfiguration(byte[] data){
+        WifiManager wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
+        wifiManager.setWifiApConfiguration(WiFiConfigurationSerializer.unmarshalWifiConfig(data));
+    }
+
+    private byte[] getNetworkPolicies(){
+        NetworkPolicyManager networkPolicyManager =
+                (NetworkPolicyManager)getSystemService(NETWORK_POLICY_SERVICE);
+        return NetworkPolicySerializer
+                .marshalNetworkPolicies(networkPolicyManager.getNetworkPolicies());
+    }
+
+    private void restoreNetworkPolicies(byte[] data){
+        NetworkPolicyManager networkPolicyManager =
+                (NetworkPolicyManager)getSystemService(NETWORK_POLICY_SERVICE);
+        networkPolicyManager
+                .setNetworkPolicies(NetworkPolicySerializer.unmarshalNetworkPolicies(data));
+    }
+
     /**
      * Write an int in BigEndian into the byte array.
      * @param out byte array
@@ -1181,8 +1259,7 @@
     }
 
     private int readInt(byte[] in, int pos) {
-        int result =
-                ((in[pos    ] & 0xFF) << 24) |
+        int result =    ((in[pos    ] & 0xFF) << 24) |
                 ((in[pos + 1] & 0xFF) << 16) |
                 ((in[pos + 2] & 0xFF) <<  8) |
                 ((in[pos + 3] & 0xFF) <<  0);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/WiFiConfigurationSerializer.java b/packages/SettingsProvider/src/com/android/providers/settings/WiFiConfigurationSerializer.java
new file mode 100644
index 0000000..f9f1d3f
--- /dev/null
+++ b/packages/SettingsProvider/src/com/android/providers/settings/WiFiConfigurationSerializer.java
@@ -0,0 +1,400 @@
+/*
+ * 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.providers.settings;
+
+import android.net.IpConfiguration;
+import android.net.LinkAddress;
+import android.net.ProxyInfo;
+import android.net.StaticIpConfiguration;
+import android.net.wifi.WifiConfiguration;
+import android.util.Log;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.util.BitSet;
+
+
+/**
+ * Backup/Restore Serializer Class for com.android.net.wifi.WifiConfiguration
+ */
+public class WiFiConfigurationSerializer {
+    private static final boolean DEBUG = false;
+    private static final String TAG = "WiFiConfigSerializer";
+
+    private static final int NULL = 0;
+    private static final int NOT_NULL = 1;
+    /**
+     * Current Version of the Serializer.
+     */
+    private static int STATE_VERSION = 1;
+
+
+    /**
+     * Marshals a WifiConfig object into a byte-array.
+     *
+     * @param wifiConfig - WifiConfiguration to be Marshalled
+     * @return byte array
+     */
+
+    public static byte[] marshalWifiConfig(WifiConfiguration wifiConfig) {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        if(wifiConfig != null) {
+            DataOutputStream out = new DataOutputStream(baos);
+            try {
+                out.writeInt(STATE_VERSION);
+                out.writeInt(wifiConfig.networkId);
+                out.writeInt(wifiConfig.status);
+                out.writeInt(wifiConfig.disableReason);
+                writeString(out, wifiConfig.SSID);
+                writeString(out, wifiConfig.BSSID);
+                out.writeInt(wifiConfig.apBand);
+                out.writeInt(wifiConfig.apChannel);
+                writeString(out, wifiConfig.autoJoinBSSID);
+                writeString(out, wifiConfig.FQDN);
+                writeString(out, wifiConfig.providerFriendlyName);
+                out.writeInt(wifiConfig.roamingConsortiumIds.length);
+                for (long id : wifiConfig.roamingConsortiumIds) {
+                    out.writeLong(id);
+                }
+                writeString(out, wifiConfig.preSharedKey);
+                for (String wepKey : wifiConfig.wepKeys) {
+                    writeString(out, wepKey);
+                }
+                out.writeInt(wifiConfig.wepTxKeyIndex);
+                out.writeInt(wifiConfig.priority);
+                out.writeInt(wifiConfig.hiddenSSID ? 1 : 0);
+                out.writeInt(wifiConfig.requirePMF ? 1 : 0);
+                writeString(out, wifiConfig.updateIdentifier);
+
+                writeBitSet(out, wifiConfig.allowedKeyManagement);
+                writeBitSet(out, wifiConfig.allowedProtocols);
+                writeBitSet(out, wifiConfig.allowedAuthAlgorithms);
+                writeBitSet(out, wifiConfig.allowedPairwiseCiphers);
+                writeBitSet(out, wifiConfig.allowedGroupCiphers);
+
+
+                //IpConfiguration
+                writeIpConfiguration(out, wifiConfig.getIpConfiguration());
+
+                writeString(out, wifiConfig.dhcpServer);
+                writeString(out, wifiConfig.defaultGwMacAddress);
+                out.writeInt(wifiConfig.autoJoinStatus);
+                out.writeInt(wifiConfig.selfAdded ? 1 : 0);
+                out.writeInt(wifiConfig.didSelfAdd ? 1 : 0);
+                out.writeInt(wifiConfig.validatedInternetAccess ? 1 : 0);
+                out.writeInt(wifiConfig.ephemeral ? 1 : 0);
+                out.writeInt(wifiConfig.creatorUid);
+                out.writeInt(wifiConfig.lastConnectUid);
+                out.writeInt(wifiConfig.lastUpdateUid);
+                writeString(out, wifiConfig.creatorName);
+                writeString(out, wifiConfig.lastUpdateName);
+                out.writeLong(wifiConfig.blackListTimestamp);
+                out.writeLong(wifiConfig.lastConnectionFailure);
+                out.writeLong(wifiConfig.lastRoamingFailure);
+                out.writeInt(wifiConfig.lastRoamingFailureReason);
+                out.writeLong(wifiConfig.roamingFailureBlackListTimeMilli);
+                out.writeLong(wifiConfig.numConnectionFailures);
+                out.writeLong(wifiConfig.numIpConfigFailures);
+                out.writeInt(wifiConfig.numAuthFailures);
+                out.writeInt(wifiConfig.numScorerOverride);
+                out.writeInt(wifiConfig.numScorerOverrideAndSwitchedNetwork);
+                out.writeInt(wifiConfig.numAssociation);
+                out.writeInt(wifiConfig.numUserTriggeredWifiDisableLowRSSI);
+                out.writeInt(wifiConfig.numUserTriggeredWifiDisableBadRSSI);
+                out.writeInt(wifiConfig.numUserTriggeredWifiDisableNotHighRSSI);
+                out.writeInt(wifiConfig.numTicksAtLowRSSI);
+                out.writeInt(wifiConfig.numTicksAtBadRSSI);
+                out.writeInt(wifiConfig.numTicksAtNotHighRSSI);
+                out.writeInt(wifiConfig.numUserTriggeredJoinAttempts);
+                out.writeInt(wifiConfig.autoJoinUseAggressiveJoinAttemptThreshold);
+                out.writeInt(wifiConfig.autoJoinBailedDueToLowRssi ? 1 : 0);
+                out.writeInt(wifiConfig.userApproved);
+                out.writeInt(wifiConfig.numNoInternetAccessReports);
+                out.writeInt(wifiConfig.noInternetAccessExpected ? 1 : 0);
+            } catch (IOException ioe) {
+                Log.e(TAG, "Failed to Convert WifiConfiguration to byte array", ioe);
+                baos.reset();
+            }
+        }
+        return baos.toByteArray();
+    }
+
+    /**
+     * Unmarshals a byte array into a WifiConfig Object
+     *
+     * @param data - marshalled WifiConfig Object
+     * @return WifiConfiguration Object
+     */
+
+    public static WifiConfiguration unmarshalWifiConfig(byte[] data) {
+        if (data == null ||  data.length == 0) {
+            return null;
+        }
+        DataInputStream in = new DataInputStream(new ByteArrayInputStream(data));
+        WifiConfiguration config = new WifiConfiguration();
+        try {
+            int version = in.readInt();
+
+            config.networkId = in.readInt();
+            config.status = in.readInt();
+            config.disableReason = in.readInt();
+            config.SSID = readString(in, version);
+            config.BSSID = readString(in, version);
+            config.apBand = in.readInt();
+            config.apChannel = in.readInt();
+            config.autoJoinBSSID = readString(in, version);
+            config.FQDN = readString(in, version);
+            config.providerFriendlyName = readString(in, version);
+            int numRoamingConsortiumIds = in.readInt();
+            config.roamingConsortiumIds = new long[numRoamingConsortiumIds];
+            for (int i = 0; i < numRoamingConsortiumIds; i++) {
+                config.roamingConsortiumIds[i] = in.readLong();
+            }
+            config.preSharedKey = readString(in, version);
+            for (int i = 0; i < config.wepKeys.length; i++) {
+                config.wepKeys[i] = readString(in, version);
+            }
+            config.wepTxKeyIndex = in.readInt();
+            config.priority = in.readInt();
+            config.hiddenSSID = in.readInt() != 0;
+            config.requirePMF = in.readInt() != 0;
+            config.updateIdentifier = readString(in, version);
+
+            config.allowedKeyManagement = readBitSet(in, version);
+            config.allowedProtocols = readBitSet(in, version);
+            config.allowedAuthAlgorithms = readBitSet(in, version);
+            config.allowedPairwiseCiphers = readBitSet(in, version);
+            config.allowedGroupCiphers = readBitSet(in, version);
+
+            //Not backed-up because EnterpriseConfig involves
+            //Certificates which are device specific.
+            //config.enterpriseConfig = new WifiEnterpriseConfig();
+
+            config.setIpConfiguration(readIpConfiguration(in, version));
+
+
+            config.dhcpServer = readString(in, version);
+            config.defaultGwMacAddress = readString(in, version);
+            config.autoJoinStatus = in.readInt();
+            config.selfAdded = in.readInt() != 0;
+            config.didSelfAdd = in.readInt() != 0;
+            config.validatedInternetAccess = in.readInt() != 0;
+            config.ephemeral = in.readInt() != 0;
+            config.creatorUid = in.readInt();
+            config.lastConnectUid = in.readInt();
+            config.lastUpdateUid = in.readInt();
+            config.creatorName = readString(in, version);
+            config.lastUpdateName = readString(in, version);
+            config.blackListTimestamp = in.readLong();
+            config.lastConnectionFailure = in.readLong();
+            config.lastRoamingFailure = in.readLong();
+            config.lastRoamingFailureReason = in.readInt();
+            config.roamingFailureBlackListTimeMilli = in.readLong();
+            config.numConnectionFailures = in.readInt();
+            config.numIpConfigFailures = in.readInt();
+            config.numAuthFailures = in.readInt();
+            config.numScorerOverride = in.readInt();
+            config.numScorerOverrideAndSwitchedNetwork = in.readInt();
+            config.numAssociation = in.readInt();
+            config.numUserTriggeredWifiDisableLowRSSI = in.readInt();
+            config.numUserTriggeredWifiDisableBadRSSI = in.readInt();
+            config.numUserTriggeredWifiDisableNotHighRSSI = in.readInt();
+            config.numTicksAtLowRSSI = in.readInt();
+            config.numTicksAtBadRSSI = in.readInt();
+            config.numTicksAtNotHighRSSI = in.readInt();
+            config.numUserTriggeredJoinAttempts = in.readInt();
+            config.autoJoinUseAggressiveJoinAttemptThreshold = in.readInt();
+            config.autoJoinBailedDueToLowRssi = in.readInt() != 0;
+            config.userApproved = in.readInt();
+            config.numNoInternetAccessReports = in.readInt();
+            config.noInternetAccessExpected = in.readInt() != 0;
+        } catch (IOException ioe) {
+            Log.e(TAG, "Failed to convert byte array to WifiConfiguration object", ioe);
+            return null;
+        }
+        return config;
+    }
+
+    private static ProxyInfo readProxyInfo(DataInputStream in, int version) throws IOException {
+        int isNull = in.readByte();
+        if (isNull == NULL) return null;
+        String host = readString(in, version);
+        int port = in.readInt();
+        String exclusionList = readString(in, version);
+        return new ProxyInfo(host, port, exclusionList);
+    }
+
+    private static void writeProxyInfo(DataOutputStream out, ProxyInfo proxyInfo) throws IOException {
+        if (proxyInfo != null) {
+            out.writeByte(NOT_NULL);
+            writeString(out, proxyInfo.getHost());
+            out.writeInt(proxyInfo.getPort());
+            writeString(out, proxyInfo.getExclusionListAsString());
+        } else {
+            out.writeByte(NULL);
+        }
+    }
+
+    private static InetAddress readInetAddress(DataInputStream in, int version) throws IOException {
+        int isNull = in.readByte();
+        if (isNull == NULL) return null;
+        InetAddress address = null;
+        int addressLength = in.readInt();
+        if (addressLength < 1) return address;
+        byte[] addressBytes = new byte[addressLength];
+        in.read(addressBytes, 0, addressLength);
+        try {
+            address = InetAddress.getByAddress(addressBytes);
+        } catch (UnknownHostException unknownHostException) {
+            return null;
+        }
+        return address;
+    }
+
+    private static void writeInetAddress(DataOutputStream out, InetAddress address) throws IOException {
+        if (address.getAddress() != null) {
+            out.writeByte(NOT_NULL);
+            out.writeInt(address.getAddress().length);
+            out.write(address.getAddress(), 0, address.getAddress().length);
+        } else {
+            out.writeByte(NULL);
+        }
+    }
+
+    private static LinkAddress readLinkAddress(DataInputStream in, int version) throws IOException {
+        int isNull = in.readByte();
+        if (isNull == NULL) return null;
+        InetAddress address = readInetAddress(in, version);
+        int prefixLength = in.readInt();
+        int flags = in.readInt();
+        int scope = in.readInt();
+        return new LinkAddress(address, prefixLength, flags, scope);
+    }
+
+    private static void writeLinkAddress(DataOutputStream out, LinkAddress address) throws IOException {
+        if (address != null) {
+            out.writeByte(NOT_NULL);
+            writeInetAddress(out, address.getAddress());
+            out.writeInt(address.getPrefixLength());
+            out.writeInt(address.getFlags());
+            out.writeInt(address.getScope());
+        } else {
+            out.writeByte(NULL);
+        }
+    }
+
+    private static StaticIpConfiguration readStaticIpConfiguration(DataInputStream in, int version) throws IOException {
+        int isNull = in.readByte();
+        if (isNull == NULL) return null;
+        StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
+        staticIpConfiguration.ipAddress = readLinkAddress(in, version);
+        staticIpConfiguration.gateway = readInetAddress(in, version);
+        int dnsServersLength = in.readInt();
+        for (int i = 0; i < dnsServersLength; i++) {
+            staticIpConfiguration.dnsServers.add(readInetAddress(in, version));
+        }
+        staticIpConfiguration.domains = readString(in, version);
+        return staticIpConfiguration;
+    }
+
+    private static void writeStaticIpConfiguration(DataOutputStream out, StaticIpConfiguration staticIpConfiguration) throws IOException {
+        if (staticIpConfiguration != null) {
+            out.writeByte(NOT_NULL);
+            writeLinkAddress(out, staticIpConfiguration.ipAddress);
+            writeInetAddress(out, staticIpConfiguration.gateway);
+            out.writeInt(staticIpConfiguration.dnsServers.size());
+            for (InetAddress inetAddress : staticIpConfiguration.dnsServers) {
+                writeInetAddress(out, inetAddress);
+            }
+            writeString(out, staticIpConfiguration.domains);
+        } else {
+            out.writeByte(NULL);
+        }
+    }
+
+    private static IpConfiguration readIpConfiguration(DataInputStream in, int version) throws IOException {
+        int isNull = in.readByte();
+        if (isNull == NULL) return null;
+        IpConfiguration ipConfiguration = new IpConfiguration();
+        String tmp = readString(in, version);
+        ipConfiguration.ipAssignment = tmp == null ? null : IpConfiguration.IpAssignment.valueOf(tmp);
+        tmp = readString(in, version);
+        ipConfiguration.proxySettings = tmp == null ? null : IpConfiguration.ProxySettings.valueOf(tmp);
+        ipConfiguration.staticIpConfiguration = readStaticIpConfiguration(in, version);
+        ipConfiguration.httpProxy = readProxyInfo(in, version);
+        return ipConfiguration;
+    }
+
+
+    private static void writeIpConfiguration(DataOutputStream out, IpConfiguration ipConfiguration) throws IOException {
+        if (ipConfiguration != null) {
+            out.writeByte(NOT_NULL);
+            writeString(out, ipConfiguration.ipAssignment != null ? ipConfiguration.ipAssignment.name() : null);
+            writeString(out, ipConfiguration.proxySettings != null ? ipConfiguration.proxySettings.name() : null);
+            writeStaticIpConfiguration(out, ipConfiguration.staticIpConfiguration);
+            writeProxyInfo(out, ipConfiguration.httpProxy);
+        } else {
+            out.writeByte(NULL);
+        }
+
+    }
+
+    private static String readString(DataInputStream in, int version) throws IOException {
+        byte isNull = in.readByte();
+        if (isNull == NOT_NULL) {
+            return in.readUTF();
+        }
+        return null;
+    }
+
+    private static void writeString(DataOutputStream out, String val) throws IOException {
+        if (val != null) {
+            out.writeByte(NOT_NULL);
+            out.writeUTF(val);
+        } else {
+            out.writeByte(NULL);
+        }
+    }
+
+    private static BitSet readBitSet(DataInputStream in, int version) throws IOException {
+        byte isNull = in.readByte();
+        if (isNull == NOT_NULL) {
+            int length = in.readInt();
+            byte[] bytes = new byte[length];
+            in.read(bytes, 0, length);
+            return BitSet.valueOf(bytes);
+        }
+        return new BitSet();
+    }
+
+    private static void writeBitSet(DataOutputStream out, BitSet val) throws IOException {
+        if (val != null) {
+            out.writeByte(NOT_NULL);
+            byte[] byteArray = val.toByteArray();
+            out.writeInt(byteArray.length);
+            out.write(byteArray);
+        } else {
+            out.writeByte(NULL);
+        }
+    }
+}
diff --git a/packages/SettingsProvider/test/Android.mk b/packages/SettingsProvider/test/Android.mk
index ef863e7..f278967 100644
--- a/packages/SettingsProvider/test/Android.mk
+++ b/packages/SettingsProvider/test/Android.mk
@@ -5,7 +5,10 @@
 # Note we statically link SettingsState to do some unit tests.  It's not accessible otherwise
 # because this test is not an instrumentation test. (because the target runs in the system process.)
 LOCAL_SRC_FILES := $(call all-subdir-java-files) \
-    ../src/com/android/providers/settings/SettingsState.java
+    ../src/com/android/providers/settings/SettingsState.java \
+    ../src/com/android/providers/settings/WiFiConfigurationSerializer.java \
+    ../src/com/android/providers/settings/NetworkPolicySerializer.java
+
 
 LOCAL_PACKAGE_NAME := SettingsProviderTest
 
@@ -13,4 +16,4 @@
 
 LOCAL_CERTIFICATE := platform
 
-include $(BUILD_PACKAGE)
\ No newline at end of file
+include $(BUILD_PACKAGE)
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/NetworkPolicySerializerTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/NetworkPolicySerializerTest.java
new file mode 100644
index 0000000..1986596
--- /dev/null
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/NetworkPolicySerializerTest.java
@@ -0,0 +1,117 @@
+package com.android.providers.settings;
+
+import android.net.NetworkPolicy;
+import android.net.NetworkTemplate;
+import android.test.AndroidTestCase;
+
+import java.util.Random;
+
+/**
+ * Tests for NetworkPolicySerializer
+ */
+public class NetworkPolicySerializerTest extends AndroidTestCase {
+    static Random sRandom = new Random();
+
+    public void testMarshallAndUnmarshalNetworkPolicy() {
+        NetworkPolicy policy = getDummyNetworkPolicy();
+        byte[] data = NetworkPolicySerializer.marshalNetworkPolicy(policy);
+        assertNotNull("Got Null data from marshal", data);
+        assertFalse("Got back an empty byte[] from marshal", data.length == 0);
+
+        NetworkPolicy unmarshaled = NetworkPolicySerializer.unmarshalNetworkPolicy(data);
+        assertNotNull("Got Null data from unmarshaled", unmarshaled);
+        assertTrue("NetworkPolicy Marshall and Unmarshal Failed!", policy.equals(unmarshaled));
+    }
+
+    public void testMarshallNetworkPolicyEdgeCases() {
+        byte[] data = NetworkPolicySerializer.marshalNetworkPolicy(null);
+        assertNotNull("NetworkPolicy marshal returned null. Expected: byte[0]", data);
+        assertEquals("NetworkPolicy marshal returned incomplete byte array. Expected: byte[0]",
+                data.length, 0);
+    }
+
+    public void testUnmarshallNetworkPolicyEdgeCases() {
+        NetworkPolicy policy = NetworkPolicySerializer.unmarshalNetworkPolicy(null);
+        assertNull("Non null NetworkPolicy returned for null byte[] input", policy);
+
+        policy = NetworkPolicySerializer.unmarshalNetworkPolicy(new byte[0]);
+        assertNull("Non null NetworkPolicy returned for empty byte[] input", policy);
+
+        policy = NetworkPolicySerializer.unmarshalNetworkPolicy(new byte[]{10, 20, 30, 40, 50, 60});
+        assertNull("Non null NetworkPolicy returned for incomplete byte[] input", policy);
+    }
+
+    public void testMarshallAndUnmarshalNetworkPolicies() {
+        NetworkPolicy[] policies = getDummyNetworkPolicies(5);
+        byte[] data = NetworkPolicySerializer.marshalNetworkPolicies(policies);
+        assertNotNull("Got Null data from marshal", data);
+        assertFalse("Got back an empty byte[] from marshal", data.length == 0);
+
+        NetworkPolicy[] unmarshaled = NetworkPolicySerializer.unmarshalNetworkPolicies(data);
+        assertNotNull("Got Null data from unmarshaled", unmarshaled);
+        try {
+            for (int i = 0; i < policies.length; i++) {
+                assertTrue("NetworkPolicies Marshall and Unmarshal Failed!",
+                        policies[i].equals(unmarshaled[i]));
+            }
+        } catch (NullPointerException npe) {
+            assertTrue("Some policies were not marshaled/unmarshaled correctly", false);
+        }
+    }
+
+    public void testMarshallNetworkPoliciesEdgeCases() {
+        byte[] data = NetworkPolicySerializer.marshalNetworkPolicies(null);
+        assertNotNull("NetworkPolicies marshal returned null!", data);
+        assertEquals("NetworkPolicies marshal returned incomplete byte array", data.length, 0);
+
+        data = NetworkPolicySerializer.marshalNetworkPolicies(new NetworkPolicy[0]);
+        assertNotNull("NetworkPolicies marshal returned null for empty NetworkPolicy[]", data);
+        assertEquals("NetworkPolicies marshal returned incomplete byte array for empty NetworkPolicy[]"
+                , data.length, 0);
+    }
+
+    public void testUnmarshalNetworkPoliciesEdgeCases() {
+        NetworkPolicy[] policies = NetworkPolicySerializer.unmarshalNetworkPolicies(null);
+        assertNotNull("NetworkPolicies unmarshal returned null for null input. Expected: byte[0] ",
+                policies);
+        assertEquals("Non Empty NetworkPolicy[] returned for null input Expected: byte[0]",
+                policies.length, 0);
+
+        policies = NetworkPolicySerializer.unmarshalNetworkPolicies(new byte[0]);
+        assertNotNull("NetworkPolicies unmarshal returned null for empty byte[] input. Expected: byte[0]",
+                policies);
+        assertEquals("Non Empty NetworkPolicy[] returned for empty byte[] input. Expected: byte[0]",
+                policies.length, 0);
+
+        policies = NetworkPolicySerializer.unmarshalNetworkPolicies(new byte[]{10, 20, 30, 40, 50, 60});
+        assertNotNull("NetworkPolicies unmarshal returned null for incomplete byte[] input. " +
+                "Expected: byte[0] ", policies);
+        assertEquals("Non Empty NetworkPolicy[] returned for incomplete byte[] input Expected: byte[0]",
+                policies.length, 0);
+
+    }
+
+    private NetworkPolicy[] getDummyNetworkPolicies(int num) {
+        NetworkPolicy[] policies = new NetworkPolicy[num];
+        for (int i = 0; i < num; i++) {
+            policies[i] = getDummyNetworkPolicy();
+        }
+        return policies;
+    }
+
+    private NetworkPolicy getDummyNetworkPolicy() {
+        NetworkTemplate template = new NetworkTemplate(NetworkTemplate.MATCH_MOBILE_ALL, "subId",
+                "GoogleGuest");
+        int cycleDay = sRandom.nextInt();
+        String cycleTimezone = "timezone";
+        long warningBytes = sRandom.nextLong();
+        long limitBytes = sRandom.nextLong();
+        long lastWarningSnooze = sRandom.nextLong();
+        long lastLimitSnooze = sRandom.nextLong();
+        boolean metered = sRandom.nextInt() % 2 == 0;
+        boolean inferred = sRandom.nextInt() % 2 == 0;
+        return new NetworkPolicy(template, cycleDay, cycleTimezone, warningBytes, limitBytes,
+                lastWarningSnooze, lastLimitSnooze, metered, inferred);
+    }
+
+}
diff --git a/packages/Shell/res/values-af/strings.xml b/packages/Shell/res/values-af/strings.xml
index a9960d1..8c4de4e 100644
--- a/packages/Shell/res/values-af/strings.xml
+++ b/packages/Shell/res/values-af/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Tuisskerm"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Foutverslag word tans gegenereer"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Foutverslag vasgevang"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Swiep na links om jou foutverslag te deel"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Raak om jou foutverslag te deel"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Wys hierdie boodskap volgende keer"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Foutverslae"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Foutverslaglêer kon nie gelees word nie"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"naamloos"</string>
 </resources>
diff --git a/packages/Shell/res/values-bn-rBD/strings.xml b/packages/Shell/res/values-bn-rBD/strings.xml
index f37e88a..afa3a46 100644
--- a/packages/Shell/res/values-bn-rBD/strings.xml
+++ b/packages/Shell/res/values-bn-rBD/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"শেল"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"ত্রুটির প্রতিবেদন তৈরি করা হচ্ছে"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"ত্রুটির প্রতিবেদন নেওয়া হয়েছে"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"আপনার বাগ রিপোর্ট শেয়ার করতে বামে সোয়াইপ করুন"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"আপনার ত্রুটির প্রতিবেদন ভাগ করতে স্পর্শ করুন"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"এই বার্তাটি পরের বার দেখান"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"ত্রুটির প্রতিবেদনগুলি"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"ত্রুটির প্রতিবেদনের ফাইলটি পড়া যায়নি"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"নামবিহীন"</string>
 </resources>
diff --git a/packages/Shell/res/values-ca/strings.xml b/packages/Shell/res/values-ca/strings.xml
index f8652cf..188da67 100644
--- a/packages/Shell/res/values-ca/strings.xml
+++ b/packages/Shell/res/values-ca/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Protecció"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"S\'està generant l\'informe d\'errors"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"S\'ha registrat l\'informe d\'error"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Llisca cap a l\'esquerra per compartir l\'informe d\'errors."</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Toca aquí per compartir el teu informe d\'error."</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostra aquest missatge la propera vegada"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Informes d\'error"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"No s\'ha pogut llegir el fitxer de l\'informe d\'errors"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"sense nom"</string>
 </resources>
diff --git a/packages/Shell/res/values-cs/strings.xml b/packages/Shell/res/values-cs/strings.xml
index 1647b2b..fdc8023 100644
--- a/packages/Shell/res/values-cs/strings.xml
+++ b/packages/Shell/res/values-cs/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Vytváří se zpráva o chybě"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Bylo vytvořeno chybové hlášení"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Chcete-li hlášení chyby sdílet, přejeďte doleva."</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Chybové hlášení můžete sdílet klepnutím."</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Zobrazit tuto zprávu příště"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Zprávy o chybách"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Soubor chybové zprávy nelze načíst"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"bez názvu"</string>
 </resources>
diff --git a/packages/Shell/res/values-de/strings.xml b/packages/Shell/res/values-de/strings.xml
index ef83da6..13c1c96 100644
--- a/packages/Shell/res/values-de/strings.xml
+++ b/packages/Shell/res/values-de/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Fehlerbericht wird generiert"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Fehlerbericht erfasst"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Wischen Sie nach links, um Ihren Fehlerbericht zu teilen."</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Tippen, um Fehlerbericht zu teilen"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Diese Nachricht nächstes Mal zeigen"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Fehlerberichte"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Fehlerberichtdatei konnte nicht gelesen werden."</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"Unbenannt"</string>
 </resources>
diff --git a/packages/Shell/res/values-el/strings.xml b/packages/Shell/res/values-el/strings.xml
index c437798..aa03bec 100644
--- a/packages/Shell/res/values-el/strings.xml
+++ b/packages/Shell/res/values-el/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Κέλυφος"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Δημιουργείται αναφορά σφάλματος"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Η λήψη της αναφοράς ήταν επιτυχής"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Σύρετε προς τα αριστερά για κοινή χρήση της αναφοράς σφαλμάτων"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Αγγίξτε για να μοιραστείτε τη αναφορά σφαλμάτων"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Εμφάνιση αυτού του μηνύματος την επόμενη φορά"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Αναφορές σφαλμάτων"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Δεν ήταν δυνατή η ανάγνωση του αρχείου της αναφοράς σφαλμάτων"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"ανώνυμη"</string>
 </resources>
diff --git a/packages/Shell/res/values-es-rUS/strings.xml b/packages/Shell/res/values-es-rUS/strings.xml
index 3a204a2..ab2dd63 100644
--- a/packages/Shell/res/values-es-rUS/strings.xml
+++ b/packages/Shell/res/values-es-rUS/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"El informe de errores se está generando"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Informe de errores capturado"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Desliza el dedo hacia la izquierda para compartir el informe de errores."</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Toca para compartir tu informe de errores."</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar este mensaje la próxima vez"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Informes de errores"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"No se pudo leer el archivo de informe de errores"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"sin nombre"</string>
 </resources>
diff --git a/packages/Shell/res/values-et-rEE/strings.xml b/packages/Shell/res/values-et-rEE/strings.xml
index 2e1e037..3edefa4 100644
--- a/packages/Shell/res/values-et-rEE/strings.xml
+++ b/packages/Shell/res/values-et-rEE/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Kest"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Veaaruande loomine"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Veaaruanne jäädvustati"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Veaaruande jagamiseks pühkige vasakule"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Veaaruande jagamiseks puudutage"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Kuva see sõnum järgmisel korral"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Veaaruanded"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Veaaruande faili ei õnnestunud lugeda"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"nimeta"</string>
 </resources>
diff --git a/packages/Shell/res/values-fa/strings.xml b/packages/Shell/res/values-fa/strings.xml
index 578bb44..409fd53 100644
--- a/packages/Shell/res/values-fa/strings.xml
+++ b/packages/Shell/res/values-fa/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"گزارش اشکال در حال ایجاد شدن است"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"گزارش اشکال دریافت شد"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"برای اشتراک‌گذاری گزارش اشکال، به تندی آن را به چپ بکشید"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"جهت اشتراک‌گذاری گزارش اشکال خود لمس کنید"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"دفعه بعد این پیام نشان داده شود"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"گزارش اشکال"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"فایل گزارش اشکال خوانده نشد"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"بی‌نام"</string>
 </resources>
diff --git a/packages/Shell/res/values-fr-rCA/strings.xml b/packages/Shell/res/values-fr-rCA/strings.xml
index df5893e..4dc4482 100644
--- a/packages/Shell/res/values-fr-rCA/strings.xml
+++ b/packages/Shell/res/values-fr-rCA/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Le rapport de bogue est en cours de création"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Rapport de bogue enregistré"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Faites glisser le doigt vers la gauche pour partager votre rapport de bogue."</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Appuyer ici pour partager votre rapport de bogue"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Afficher ce message la prochaine fois"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Rapports de bogues"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Impossible de lire le fichier du rapport de bogue"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"sans nom"</string>
 </resources>
diff --git a/packages/Shell/res/values-fr/strings.xml b/packages/Shell/res/values-fr/strings.xml
index 52d4543..a3e4f7d 100644
--- a/packages/Shell/res/values-fr/strings.xml
+++ b/packages/Shell/res/values-fr/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Le rapport de bug est en cours de création."</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Rapport de bug enregistré"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Faites glisser le doigt vers la gauche pour partager votre rapport d\'erreur."</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Appuyez ici pour partager le rapport de bug"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Afficher ce message la prochaine fois"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Rapports d\'erreur"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Impossible de lire le fichier de rapport de bug."</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"sans nom"</string>
 </resources>
diff --git a/packages/Shell/res/values-gl-rES/strings.xml b/packages/Shell/res/values-gl-rES/strings.xml
index f9af246..8b28caa 100644
--- a/packages/Shell/res/values-gl-rES/strings.xml
+++ b/packages/Shell/res/values-gl-rES/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Estase xerando o informe de erro"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Informe de erros rexistrado"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Pasa o dedo á esquerda para compartir o teu informe de erros"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Toca aquí para compartir o teu informe de erros"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar esta mensaxe a próxima vez"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Informes de erros"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Non se puido ler o ficheiro de informe de erros"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"sen nome"</string>
 </resources>
diff --git a/packages/Shell/res/values-hr/strings.xml b/packages/Shell/res/values-hr/strings.xml
index ce45c50..1957bdb 100644
--- a/packages/Shell/res/values-hr/strings.xml
+++ b/packages/Shell/res/values-hr/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Ljuska"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Generira se izvješće o programskoj pogrešci"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Prijava programske pogreške snimljena je"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Prijeđite prstom ulijevo da biste poslali izvješće o programskim pogreškama"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Dodirnite za dijeljenje prijave programske pogreške"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Prikaži tu poruku sljedeći put"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Izvj. o prog. pogreš."</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Izvješće o programskoj pogrešci nije pročitano"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"bez naziva"</string>
 </resources>
diff --git a/packages/Shell/res/values-hy-rAM/strings.xml b/packages/Shell/res/values-hy-rAM/strings.xml
index dac4c25..317cb0b 100644
--- a/packages/Shell/res/values-hy-rAM/strings.xml
+++ b/packages/Shell/res/values-hy-rAM/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Խեցի"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Վրիպակի զեկույցը ստեղծվում է"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Վրիպակի զեկույց է ստացվել"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Սահեցրեք ձախ՝ սխալի հաշվետվությունը համօգտագործելու համար"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Հպեք` ձեր վրիպակի մասին զեկույցը տարածելու համար"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Այս հաղորդագրությունը ցույց տալ հաջորդ անգամ"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Վրիպակների հաշվետվություններ"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Հնարավոր չէ կարդալ վրիպակների զեկույցի ֆայլը"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"անանուն"</string>
 </resources>
diff --git a/packages/Shell/res/values-is-rIS/strings.xml b/packages/Shell/res/values-is-rIS/strings.xml
index 495ec55..39605db 100644
--- a/packages/Shell/res/values-is-rIS/strings.xml
+++ b/packages/Shell/res/values-is-rIS/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Skipanalína"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Verið er að búa til villutilkynningu"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Villutilkynning útbúin"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Strjúktu til vinstri til að deila villuskýrslunni"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Snertu til að deila villutilkynningunni"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Sýna þessi skilaboð næst"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Villutilkynningar"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Ekki var hægt að lesa úr villuskýrslunni"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"án heitis"</string>
 </resources>
diff --git a/packages/Shell/res/values-ja/strings.xml b/packages/Shell/res/values-ja/strings.xml
index 11533e0..fd4a150 100644
--- a/packages/Shell/res/values-ja/strings.xml
+++ b/packages/Shell/res/values-ja/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"シェル"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"バグレポートを生成しています"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"バグレポートが記録されました"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"バグレポートを共有するには左にスワイプ"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"バグレポートを共有するにはタップします"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"このメッセージを次回も表示する"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"バグレポート"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"バグレポート ファイルを読み取ることができませんでした"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"名前なし"</string>
 </resources>
diff --git a/packages/Shell/res/values-ka-rGE/strings.xml b/packages/Shell/res/values-ka-rGE/strings.xml
index 5d1a417..802f944 100644
--- a/packages/Shell/res/values-ka-rGE/strings.xml
+++ b/packages/Shell/res/values-ka-rGE/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"გარეკანი"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"მიმდინარეობს ხარვეზის შესახებ ანგარიშის გენერირება"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"ანგარიში ხარვეზების შესახებ შექმნილია"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"გაასრიალეთ მარცხნივ თქვენი ხარვეზის შეტყობინების გასაზიარებლად"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"შეეხეთ თქვენი ხარვეზების ანგარიშის გასაზიარებლად"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"შემდგომში აჩვენე ეს შეტყობინება"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"შეცდომების ანგარიშები"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"ხარვეზების შესახებ ანგარიშის წაკითხვა ვერ მოხერხდა"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"უსახელო"</string>
 </resources>
diff --git a/packages/Shell/res/values-ko/strings.xml b/packages/Shell/res/values-ko/strings.xml
index 8ef29db..5e96e6d 100644
--- a/packages/Shell/res/values-ko/strings.xml
+++ b/packages/Shell/res/values-ko/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"셸"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"버그 신고 생성 중"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"버그 신고서 캡처됨"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"왼쪽으로 스와이프하여 버그 신고서를 공유하세요."</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"버그 신고서를 공유하려면 터치하세요."</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"다음에 이 메시지 표시"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"버그 신고"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"버그 신고 파일을 읽을 수 없습니다."</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"이름 없음"</string>
 </resources>
diff --git a/packages/Shell/res/values-ky-rKG/strings.xml b/packages/Shell/res/values-ky-rKG/strings.xml
index cf043b2..aafeb24 100644
--- a/packages/Shell/res/values-ky-rKG/strings.xml
+++ b/packages/Shell/res/values-ky-rKG/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Командалык кабык"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Мүчүлүштүктөр тууралуу билдирүү өндүрүлүүдө"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Ката тууралуу билдирүү түзүлдү"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Ката жөнүндө кабар менен бөлүшүү үчүн солго серпип коюңуз"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Ката тууралуу билдирүүңүздү жөнөтүш үчүн, тийиңиз"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Бул билдирүү кийин көрсөтүлсүн"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Мүчүлүштүктөрдү кабарлоолор"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Мүчүлүштүк тууралуу кабарлаган файл окулбай койду"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"аты жок"</string>
 </resources>
diff --git a/packages/Shell/res/values-mk-rMK/strings.xml b/packages/Shell/res/values-mk-rMK/strings.xml
index 1c5453e..0f3ed5a 100644
--- a/packages/Shell/res/values-mk-rMK/strings.xml
+++ b/packages/Shell/res/values-mk-rMK/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Обвивка"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Се генерира извештајот за грешки"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Извештајот за грешка е снимен"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Повлечете налево за да споделите пријава за грешка"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Допри да се сподели твојот извештај за грешка"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Прикажи ја поракава следниот пат"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Извештаи за грешки"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Датотеката со извештај за грешка не можеше да се прочита"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"неименувани"</string>
 </resources>
diff --git a/packages/Shell/res/values-mn-rMN/strings.xml b/packages/Shell/res/values-mn-rMN/strings.xml
index 1ca6f00..8f6a2b0 100644
--- a/packages/Shell/res/values-mn-rMN/strings.xml
+++ b/packages/Shell/res/values-mn-rMN/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Шел"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Алдааны тайланг үүсгэсэн"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Алдааны мэдээлэл хүлээн авав"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Өөрийн согог репортыг хуваалцахын тулд зүүн шудрана уу"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Та алдааны мэдэгдлийг хуваалцах бол хүрнэ үү"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Энэ мессежийг дараагийн удаа харуулах"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Гэмтлийн тухай тайлан"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Алдааны тайлангийн файлыг уншиж чадахгүй байна"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"нэр байхгүй"</string>
 </resources>
diff --git a/packages/Shell/res/values-ms-rMY/strings.xml b/packages/Shell/res/values-ms-rMY/strings.xml
index 4c39d92..4491add 100644
--- a/packages/Shell/res/values-ms-rMY/strings.xml
+++ b/packages/Shell/res/values-ms-rMY/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Laporan pepijat sedang dijanakan"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Laporan pepijat telah ditangkap"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Leret ke kiri untuk berkongsi laporan pepijat anda"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Sentuh untuk berkongsi laporan pepijat anda"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Tunjukkan mesej ini pada masa akan datang"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Laporan pepijat"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Fail laporan pepijat tidak dapat dibaca"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"tidak bernama"</string>
 </resources>
diff --git a/packages/Shell/res/values-nb/strings.xml b/packages/Shell/res/values-nb/strings.xml
index 49214e0..14a873c 100644
--- a/packages/Shell/res/values-nb/strings.xml
+++ b/packages/Shell/res/values-nb/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Kommandoliste"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Feilrapporten blir generert"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Feilrapporten er lagret"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Sveip til venstre for å dele feilrapporten din"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Trykk for å dele feilrapporten din"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Vis denne meldingen neste gang"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Feilrapporter"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Feilrapportfilen kunne ikke leses"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"uten navn"</string>
 </resources>
diff --git a/packages/Shell/res/values-nl/strings.xml b/packages/Shell/res/values-nl/strings.xml
index 71d068b..9bfce94 100644
--- a/packages/Shell/res/values-nl/strings.xml
+++ b/packages/Shell/res/values-nl/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Bugrapport wordt gegenereerd"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Foutenrapport vastgelegd"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Veeg naar links om je bugmelding te delen"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Raak aan om je foutenrapport te delen"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Dit bericht de volgende keer weergeven"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Foutenrapporten"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Bestand met bugrapport kan niet worden gelezen"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"naamloos"</string>
 </resources>
diff --git a/packages/Shell/res/values-pl/strings.xml b/packages/Shell/res/values-pl/strings.xml
index f79c198..0c8a6b4 100644
--- a/packages/Shell/res/values-pl/strings.xml
+++ b/packages/Shell/res/values-pl/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Powłoka"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Trwa generowanie raportu o błędzie"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Raport o błędach został zapisany"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Przesuń palcem w lewo, by udostępnić swoje zgłoszenie błędu"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Kliknij, by udostępnić raport o błędach"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Pokaż ten komunikat następnym razem"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Raporty o błędach"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Nie można odczytać raportu o błędzie"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"bez nazwy"</string>
 </resources>
diff --git a/packages/Shell/res/values-pt-rPT/strings.xml b/packages/Shell/res/values-pt-rPT/strings.xml
index a025cbc..417c444 100644
--- a/packages/Shell/res/values-pt-rPT/strings.xml
+++ b/packages/Shell/res/values-pt-rPT/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"O relatório de erro está a ser gerado"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Relatório de erros capturado"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Deslizar rapidamente para a esquerda para partilhar o seu relatório de erros"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Toque para partilhar o relatório de erros"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar esta mensagem da próxima vez"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Relatórios de erros"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Não foi possível ler o ficheiro de relatório de erro"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"sem nome"</string>
 </resources>
diff --git a/packages/Shell/res/values-ro/strings.xml b/packages/Shell/res/values-ro/strings.xml
index ac14e90..132f21f 100644
--- a/packages/Shell/res/values-ro/strings.xml
+++ b/packages/Shell/res/values-ro/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Se generează raportul de eroare"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Raportul despre erori a fost creat"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Glisați la stânga pentru a trimite raportul de erori"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Atingeți pentru a permite accesul la raportul despre erori"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Afișați acest mesaj data viitoare"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Rapoarte de erori"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Fișierul cu raportul de eroare nu a putut fi citit"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"fără nume"</string>
 </resources>
diff --git a/packages/Shell/res/values-sl/strings.xml b/packages/Shell/res/values-sl/strings.xml
index a4c3061..91041e1 100644
--- a/packages/Shell/res/values-sl/strings.xml
+++ b/packages/Shell/res/values-sl/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Lupina"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Poročilo o napakah se pripravlja"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Poročilo o napaki je posneto"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Povlecite v levo, če želite poslati sporočilo o napaki"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Dotaknite se, če želite deliti sporočilo o napaki z drugimi"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Pokaži to sporočilo naslednjič"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Poročila o napakah"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Datoteke s poročilom o napakah ni bilo mogoče prebrati"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"neimenovano"</string>
 </resources>
diff --git a/packages/Shell/res/values-sq-rAL/strings.xml b/packages/Shell/res/values-sq-rAL/strings.xml
index fe100f2..e91aa09 100644
--- a/packages/Shell/res/values-sq-rAL/strings.xml
+++ b/packages/Shell/res/values-sq-rAL/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Guaska"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Po krijohet raporti i defekteve në kod"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Raporti i defektit në kod u regjistrua"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Rrëshqit majtas për të ndarë raportin e defektit në kod"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Prek për të ndarë raportin e defektit në kod"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Tregoje këtë mesazh herën tjetër"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Raportet e gabimeve"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Skedari i raportimit të defektit në kod nuk mund të lexohej."</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"e paemërtuar"</string>
 </resources>
diff --git a/packages/Shell/res/values-sr/strings.xml b/packages/Shell/res/values-sr/strings.xml
index d873591..1be47da 100644
--- a/packages/Shell/res/values-sr/strings.xml
+++ b/packages/Shell/res/values-sr/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Извештај о грешци се генерише"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Извештај о грешци је снимљен"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Превуците улево да бисте делили извештај о грешкама"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Додирните да бисте делили извештај о грешци"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Прикажи ову поруку следећи пут"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Извештаји о грешкама"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Датотека извештаја о грешци не може да се прочита"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"неименовано"</string>
 </resources>
diff --git a/packages/Shell/res/values-sv/strings.xml b/packages/Shell/res/values-sv/strings.xml
index 65bc055..9f5b5f0 100644
--- a/packages/Shell/res/values-sv/strings.xml
+++ b/packages/Shell/res/values-sv/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Skal"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Felrapporten genereras"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Felrapporten har skapats"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Svep åt vänster om du vill dela felrapporten"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Tryck om du vill dela felrapporten"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Visa det här meddelandet nästa gång"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Felrapporter"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Det gick inte att läsa felrapporten"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"namnlös"</string>
 </resources>
diff --git a/packages/Shell/res/values-sw/strings.xml b/packages/Shell/res/values-sw/strings.xml
index 927c4d8..422ca81 100644
--- a/packages/Shell/res/values-sw/strings.xml
+++ b/packages/Shell/res/values-sw/strings.xml
@@ -25,5 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Onyesha ujumbe huu wakati mwingine"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Ripoti za hitilafu"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Faili ya ripoti ya hitilafu haikusomwa"</string>
-    <string name="bugreport_unnamed" msgid="2800582406842092709">"isiyokuwa na jina"</string>
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"Isiyo na jina"</string>
 </resources>
diff --git a/packages/Shell/res/values-ta-rIN/strings.xml b/packages/Shell/res/values-ta-rIN/strings.xml
index 4bf3d60..31daf54 100644
--- a/packages/Shell/res/values-ta-rIN/strings.xml
+++ b/packages/Shell/res/values-ta-rIN/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"ஷெல்"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"பிழை அறிக்கை உருவாக்கப்படுகிறது"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"பிழை அறிக்கைகள் படமெடுக்கப்பட்டன"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"பிழை அறிக்கையைப் பகிர இடது புறமாகத் தேய்க்கவும்"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"உங்கள் பிழை அறிக்கையைப் பகிர, தொடவும்"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"இந்தச் செய்தியை அடுத்த முறைக் காட்டு"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"பிழை அறிக்கைகள்"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"பிழை அறிக்கையைப் படிக்க முடியவில்லை"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"பெயரிடப்படாதது"</string>
 </resources>
diff --git a/packages/Shell/res/values-th/strings.xml b/packages/Shell/res/values-th/strings.xml
index 66492de..2d9a65e 100644
--- a/packages/Shell/res/values-th/strings.xml
+++ b/packages/Shell/res/values-th/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"กำลังสร้างรายงานข้อบกพร่อง"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"จับภาพรายงานข้อบกพร่องแล้ว"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"กวาดไปทางซ้ายเพื่อแชร์รายงานข้อบกพร่อง"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"แตะเพื่อแชร์รายงานข้อบกพร่องของคุณ"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"แสดงข้อความนี้ในครั้งต่อไป"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"รายงานข้อบกพร่อง"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"ไม่สามารถอ่านไฟล์รายงานข้อบกพร่อง"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"ไม่มีชื่อ"</string>
 </resources>
diff --git a/packages/Shell/res/values-tl/strings.xml b/packages/Shell/res/values-tl/strings.xml
index f43dc9f..8fead8f 100644
--- a/packages/Shell/res/values-tl/strings.xml
+++ b/packages/Shell/res/values-tl/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Binubuo na ang ulat ng bug"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Na-capture ang ulat ng bug"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Mag-swipe pakaliwa upang ibahagi ang iyong ulat ng bug"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Pindutin upang ibahagi ang iyong ulat ng bug"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Ipakita ang mensaheng ito sa susunod"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Mga ulat sa bug"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Hindi mabasa ang file ng pag-uulat ng bug"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"walang pangalan"</string>
 </resources>
diff --git a/packages/Shell/res/values-tr/strings.xml b/packages/Shell/res/values-tr/strings.xml
index 4f7772e..e1d30cc 100644
--- a/packages/Shell/res/values-tr/strings.xml
+++ b/packages/Shell/res/values-tr/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Kabuk"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Hata raporu oluşturuluyor"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Hata raporu kaydedildi"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Hata raporunuzu paylaşmak için hızlıca sola kaydırın"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Hata raporunuzu paylaşmak için dokunun"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Bir dahaki sefere bu iletiyi göster"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Hata raporları"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Hata raporu dosyası okunamadı"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"adsız"</string>
 </resources>
diff --git a/packages/Shell/res/values-uk/strings.xml b/packages/Shell/res/values-uk/strings.xml
index 6c6d70d..f1396cb 100644
--- a/packages/Shell/res/values-uk/strings.xml
+++ b/packages/Shell/res/values-uk/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Оболонка"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Генерується повідомлення про помилку"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Звіт про помилки створено"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Проведіть пальцем ліворуч, щоб надіслати звіт про помилки"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Торкніться, щоб надіслати звіт про помилки"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Показати це повідомлення наступного разу"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Звіти про помилки"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Не вдалося прочитати звіт про помилки"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"без назви"</string>
 </resources>
diff --git a/packages/Shell/res/values-ur-rPK/strings.xml b/packages/Shell/res/values-ur-rPK/strings.xml
index c6a6851..412d230 100644
--- a/packages/Shell/res/values-ur-rPK/strings.xml
+++ b/packages/Shell/res/values-ur-rPK/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"شیل"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"بگ رپورٹ تخلیق ہو رہی ہے"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"بَگ رپورٹ کیپچر کر لی گئی"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"اپنی بگ رپورٹ کا اشتراک کرنے کیلئے بائیں سوائپ کریں"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"اپنی بَگ رپورٹ کا اشتراک کرنے کیلئے ٹچ کریں"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"یہ پیغام اگلی بار دکھائیں"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"بگ رپورٹس"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"بگ رپورٹ فائل پڑھی نہیں جا سکی"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"بغیر نام"</string>
 </resources>
diff --git a/packages/Shell/res/values-uz-rUZ/strings.xml b/packages/Shell/res/values-uz-rUZ/strings.xml
index c2cd1dc..ca46d2a 100644
--- a/packages/Shell/res/values-uz-rUZ/strings.xml
+++ b/packages/Shell/res/values-uz-rUZ/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Terminal"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Xatoliklar hisoboti tayyorlanmoqda"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"Xatolik hisobotini yozib olindi"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Xatolik hisobotini yuborish uchun barmog‘ingiz bilan chapga suring"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Xatolik hisobotini bo‘lishish uchun barmog‘ingizni tegizing."</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Ushbu xabar keyingi safar ko‘rsatilsin"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Xatoliklar hisoboti"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Xatoliklar hisoboti faylini o‘qib bo‘lmadi"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"nomsiz"</string>
 </resources>
diff --git a/packages/Shell/res/values-zh-rCN/strings.xml b/packages/Shell/res/values-zh-rCN/strings.xml
index 03af823..5a8e5f7 100644
--- a/packages/Shell/res/values-zh-rCN/strings.xml
+++ b/packages/Shell/res/values-zh-rCN/strings.xml
@@ -17,8 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
+    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"正在生成错误报告"</string>
     <string name="bugreport_finished_title" msgid="2293711546892863898">"已抓取错误报告"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"向左滑动即可分享错误报告"</string>
     <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"触摸即可分享您的错误报告"</string>
@@ -26,6 +25,5 @@
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"下次再显示这条讯息"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"错误报告"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"无法读取错误报告文件"</string>
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"未命名"</string>
 </resources>
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 79d4f17..e902589 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -66,7 +66,7 @@
 import android.widget.Toast;
 
 /**
- * Service used to keep progress of bug reports processes ({@code dumpstate}).
+ * Service used to keep progress of bugreport processes ({@code dumpstate}).
  * <p>
  * The workflow is:
  * <ol>
@@ -84,21 +84,25 @@
  * <li>{@link BugreportReceiver} receives the intent and delegates it to this service, which in
  * turn:
  * <ol>
- * <li>Updates the system notification so user can share the bug report.
+ * <li>Updates the system notification so user can share the bugreport.
  * <li>Stops monitoring that {@code dumpstate} process.
  * <li>Stops itself if it doesn't have any process left to monitor.
  * </ol>
  * </ol>
  */
 public class BugreportProgressService extends Service {
-    private static final String TAG = "Shell";
+    static final String TAG = "Shell";
     private static final boolean DEBUG = false;
 
     private static final String AUTHORITY = "com.android.shell";
 
+    // External intents sent by dumpstate.
     static final String INTENT_BUGREPORT_STARTED = "android.intent.action.BUGREPORT_STARTED";
     static final String INTENT_BUGREPORT_FINISHED = "android.intent.action.BUGREPORT_FINISHED";
+
+    // Internal intents used on notification actions.
     static final String INTENT_BUGREPORT_CANCEL = "android.intent.action.BUGREPORT_CANCEL";
+    static final String INTENT_BUGREPORT_SHARE = "android.intent.action.BUGREPORT_SHARE";
 
     static final String EXTRA_BUGREPORT = "android.intent.extra.BUGREPORT";
     static final String EXTRA_SCREENSHOT = "android.intent.extra.SCREENSHOT";
@@ -111,7 +115,7 @@
     private static final int MSG_POLL = 2;
 
     /** Polling frequency, in milliseconds. */
-    private static final long POLLING_FREQUENCY = 500;
+    static final long POLLING_FREQUENCY = 2000;
 
     /** How long (in ms) a dumpstate process will be monitored if it didn't show progress. */
     private static final long INACTIVITY_TIMEOUT = 3 * DateUtils.MINUTE_IN_MILLIS;
@@ -123,7 +127,7 @@
 
     /** System property (and value) used for stop dumpstate. */
     private static final String CTL_STOP = "ctl.stop";
-    private static final String BUGREPORT_SERVICE = "bugreport";
+    private static final String BUGREPORT_SERVICE = "bugreportplus";
 
     /** Managed dumpstate processes (keyed by pid) */
     private final SparseArray<BugreportInfo> mProcesses = new SparseArray<>();
@@ -169,10 +173,16 @@
 
     @Override
     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
-        writer.printf("Monitored dumpstate processes: \n");
         synchronized (mProcesses) {
-            for (int i = 0; i < mProcesses.size(); i++) {
-              writer.printf("\t%s\n", mProcesses.valueAt(i));
+            final int size = mProcesses.size();
+            if (size == 0) {
+                writer.printf("No monitored processes");
+                return;
+            }
+            writer.printf("Monitored dumpstate processes\n");
+            writer.printf("-----------------------------\n");
+            for (int i = 0; i < size; i++) {
+              writer.printf("%s\n", mProcesses.valueAt(i));
             }
         }
     }
@@ -180,7 +190,6 @@
     private final class ServiceHandler extends Handler {
         public ServiceHandler(Looper looper) {
             super(looper);
-            poll();
         }
 
         @Override
@@ -196,25 +205,24 @@
                 return;
             }
 
-            // At this point it's handling onStartCommand(), whose intent contains the extras
-            // originally received by BugreportReceiver.
+            // At this point it's handling onStartCommand(), with the intent passed as an Extra.
             if (!(msg.obj instanceof Intent)) {
                 // Sanity check.
                 Log.e(TAG, "Internal error: invalid msg.obj: " + msg.obj);
                 return;
             }
             final Parcelable parcel = ((Intent) msg.obj).getParcelableExtra(EXTRA_ORIGINAL_INTENT);
-            if (!(parcel instanceof Intent)) {
-                // Sanity check.
-                Log.e(TAG, "Internal error: msg.obj is missing extra " + EXTRA_ORIGINAL_INTENT);
-                return;
+            final Intent intent;
+            if (parcel instanceof Intent) {
+                // The real intent was passed to BugreportReceiver, which delegated to the service.
+                intent = (Intent) parcel;
+            } else {
+                intent = (Intent) msg.obj;
             }
-
-            final Intent intent = (Intent) parcel;
             final String action = intent.getAction();
-            int pid = intent.getIntExtra(EXTRA_PID, 0);
-            int max = intent.getIntExtra(EXTRA_MAX, -1);
-            String name = intent.getStringExtra(EXTRA_NAME);
+            final int pid = intent.getIntExtra(EXTRA_PID, 0);
+            final int max = intent.getIntExtra(EXTRA_MAX, -1);
+            final String name = intent.getStringExtra(EXTRA_NAME);
 
             if (DEBUG) Log.v(TAG, "action: " + action + ", name: " + name + ", pid: " + pid
                     + ", max: "+ max);
@@ -224,14 +232,18 @@
                         stopSelfWhenDone();
                         return;
                     }
+                    poll();
                     break;
                 case INTENT_BUGREPORT_FINISHED:
-                    if (pid == -1) {
+                    if (pid == 0) {
                         // Shouldn't happen, unless BUGREPORT_FINISHED is received from a legacy,
                         // out-of-sync dumpstate process.
                         Log.w(TAG, "Missing " + EXTRA_PID + " on intent " + intent);
                     }
-                    stopProgress(pid, intent);
+                    onBugreportFinished(pid, intent);
+                    break;
+                case INTENT_BUGREPORT_SHARE:
+                    shareBugreport(pid);
                     break;
                 case INTENT_BUGREPORT_CANCEL:
                     cancel(pid);
@@ -247,6 +259,8 @@
             if (pollProgress()) {
                 // Keep polling...
                 sendEmptyMessageDelayed(MSG_POLL, POLLING_FREQUENCY);
+            } else {
+                Log.i(TAG, "Stopped polling");
             }
         }
     }
@@ -283,7 +297,7 @@
     }
 
     /**
-     * Updates the system notification for a given bug report.
+     * Updates the system notification for a given bugreport.
      */
     private void updateProgress(BugreportInfo info) {
         if (info.max <= 0 || info.progress < 0) {
@@ -296,14 +310,8 @@
         nf.setMinimumFractionDigits(2);
         nf.setMaximumFractionDigits(2);
         final String percentText = nf.format((double) info.progress / info.max);
-
-        final Intent cancelIntent = new Intent(context, BugreportReceiver.class);
-        cancelIntent.setAction(INTENT_BUGREPORT_CANCEL);
-        cancelIntent.putExtra(EXTRA_PID, info.pid);
-        final Action cancelAction = new Action.Builder(null,
-                context.getString(com.android.internal.R.string.cancel),
-                PendingIntent.getBroadcast(context, info.pid, cancelIntent,
-                        PendingIntent.FLAG_CANCEL_CURRENT)).build();
+        final Action cancelAction = new Action.Builder(null, context.getString(
+                com.android.internal.R.string.cancel), newCancelIntent(context, info)).build();
 
         final String title = context.getString(R.string.bugreport_in_progress_title);
         final String name =
@@ -327,9 +335,19 @@
     }
 
     /**
-     * Finalizes the progress on a given process and sends the finished intent.
+     * Creates a {@link PendingIntent} for a notification action used to cancel a bugreport.
      */
-    private void stopProgress(int pid, Intent intent) {
+    private static PendingIntent newCancelIntent(Context context, BugreportInfo info) {
+        final Intent intent = new Intent(INTENT_BUGREPORT_CANCEL);
+        intent.setClass(context, BugreportProgressService.class);
+        intent.putExtra(EXTRA_PID, info.pid);
+        return PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
+    }
+
+    /**
+     * Finalizes the progress on a given bugreport and cancel its notification.
+     */
+    private void stopProgress(int pid) {
         synchronized (mProcesses) {
             if (mProcesses.indexOfKey(pid) < 0) {
                 Log.w(TAG, "PID not watched: " + pid);
@@ -340,11 +358,6 @@
         }
         if (DEBUG) Log.v(TAG, "stopProgress(" + pid + "): cancel notification");
         NotificationManager.from(getApplicationContext()).cancel(TAG, pid);
-        if (intent != null) {
-            // Bug report finished fine: send a new, different notification.
-            if (DEBUG) Log.v(TAG, "stopProgress(" + pid + "): finish bug report");
-            onBugreportFinished(pid, intent);
-        }
     }
 
     /**
@@ -353,7 +366,7 @@
     private void cancel(int pid) {
         Log.i(TAG, "Cancelling PID " + pid + " on user's request");
         SystemProperties.set(CTL_STOP, BUGREPORT_SERVICE);
-        stopProgress(pid, null);
+        stopProgress(pid);
     }
 
     /**
@@ -363,11 +376,19 @@
      */
     private boolean pollProgress() {
         synchronized (mProcesses) {
-            if (mProcesses.size() == 0) {
+            final int total = mProcesses.size();
+            if (total == 0) {
                 Log.d(TAG, "No process to poll progress.");
             }
-            for (int i = 0; i < mProcesses.size(); i++) {
+            int activeProcesses = 0;
+            for (int i = 0; i < total; i++) {
                 final int pid = mProcesses.keyAt(i);
+                final BugreportInfo info = mProcesses.valueAt(i);
+                if (info.finished) {
+                    if (DEBUG) Log.v(TAG, "Skipping finished process " + pid);
+                    continue;
+                }
+                activeProcesses++;
                 final String progressKey = DUMPSTATE_PREFIX + pid + PROGRESS_SUFFIX;
                 final int progress = SystemProperties.getInt(progressKey, 0);
                 if (progress == 0) {
@@ -375,7 +396,6 @@
                     continue;
                 }
                 final int max = SystemProperties.getInt(DUMPSTATE_PREFIX + pid + MAX_SUFFIX, 0);
-                final BugreportInfo info = mProcesses.valueAt(i);
                 final boolean maxChanged = max > 0 && max != info.max;
                 final boolean progressChanged = progress > 0 && progress != info.progress;
 
@@ -397,11 +417,12 @@
                     if (inactiveTime >= INACTIVITY_TIMEOUT) {
                         Log.w(TAG, "No progress update for process " + pid + " since "
                                 + info.getFormattedLastUpdate());
-                        stopProgress(info.pid, null);
+                        stopProgress(info.pid);
                     }
                 }
             }
-            return true;
+            if (DEBUG) Log.v(TAG, "pollProgress() total=" + total + ", actives=" + activeProcesses);
+            return activeProcesses > 0;
         }
     }
 
@@ -421,37 +442,46 @@
 
     private void onBugreportFinished(int pid, Intent intent) {
         final Context context = getApplicationContext();
-        final Configuration conf = context.getResources().getConfiguration();
-        final File bugreportFile = getFileExtra(intent, EXTRA_BUGREPORT);
-        final File screenshotFile = getFileExtra(intent, EXTRA_SCREENSHOT);
+        BugreportInfo info;
+        synchronized (mProcesses) {
+            info = mProcesses.get(pid);
+            if (info == null) {
+                // Happens when BUGREPORT_FINISHED was received without a BUGREPORT_STARTED
+                Log.v(TAG, "Creating info for untracked pid " + pid);
+                info = new BugreportInfo(context, pid);
+                mProcesses.put(pid, info);
+            }
+            info.bugreportFile = getFileExtra(intent, EXTRA_BUGREPORT);
+            info.screenshotFile = getFileExtra(intent, EXTRA_SCREENSHOT);
+        }
 
+        final Configuration conf = context.getResources().getConfiguration();
         if ((conf.uiMode & Configuration.UI_MODE_TYPE_MASK) != Configuration.UI_MODE_TYPE_WATCH) {
-            triggerLocalNotification(context, pid, bugreportFile, screenshotFile);
+            triggerLocalNotification(context, info);
         }
     }
 
     /**
      * Responsible for triggering a notification that allows the user to start a "share" intent with
-     * the bug report. On watches we have other methods to allow the user to start this intent
+     * the bugreport. On watches we have other methods to allow the user to start this intent
      * (usually by triggering it on another connected device); we don't need to display the
      * notification in this case.
      */
-    private static void triggerLocalNotification(final Context context, final int pid,
-            final File bugreportFile, final File screenshotFile) {
-        if (!bugreportFile.exists() || !bugreportFile.canRead()) {
-            Log.e(TAG, "Could not read bugreport file " + bugreportFile);
+    private static void triggerLocalNotification(final Context context, final BugreportInfo info) {
+        if (!info.bugreportFile.exists() || !info.bugreportFile.canRead()) {
+            Log.e(TAG, "Could not read bugreport file " + info.bugreportFile);
             Toast.makeText(context, context.getString(R.string.bugreport_unreadable_text),
                     Toast.LENGTH_LONG).show();
             return;
         }
 
-        boolean isPlainText = bugreportFile.getName().toLowerCase().endsWith(".txt");
+        boolean isPlainText = info.bugreportFile.getName().toLowerCase().endsWith(".txt");
         if (!isPlainText) {
             // Already zipped, send it right away.
-            sendBugreportNotification(context, pid, bugreportFile, screenshotFile);
+            sendBugreportNotification(context, info);
         } else {
             // Asynchronously zip the file first, then send it.
-            sendZippedBugreportNotification(context, pid, bugreportFile, screenshotFile);
+            sendZippedBugreportNotification(context, info);
         }
     }
 
@@ -498,17 +528,27 @@
     }
 
     /**
-     * Sends a bugreport notitication.
+     * Shares the bugreport upon user's request by issuing a {@link Intent#ACTION_SEND_MULTIPLE}
+     * intent, but issuing a warning dialog the first time.
      */
-    private static void sendBugreportNotification(Context context, int pid, File bugreportFile,
-            File screenshotFile) {
+    private void shareBugreport(int pid) {
+        final Context context = getApplicationContext();
+        final BugreportInfo info;
+        synchronized (mProcesses) {
+            info = mProcesses.get(pid);
+            if (info == null) {
+                // Should not happen, so log if it does...
+                Log.e(TAG, "INTERNAL ERROR: no info for PID " + pid + ": " + mProcesses);
+                return;
+            }
+        }
         // Files are kept on private storage, so turn into Uris that we can
         // grant temporary permissions for.
-        final Uri bugreportUri = getUri(context, bugreportFile);
-        final Uri screenshotUri = getUri(context, screenshotFile);
+        final Uri bugreportUri = getUri(context, info.bugreportFile);
+        final Uri screenshotUri = getUri(context, info.screenshotFile);
 
-        Intent sendIntent = buildSendIntent(context, bugreportUri, screenshotUri);
-        Intent notifIntent;
+        final Intent sendIntent = buildSendIntent(context, bugreportUri, screenshotUri);
+        final Intent notifIntent;
 
         // Send through warning dialog by default
         if (getWarningState(context, STATE_SHOW) == STATE_SHOW) {
@@ -518,32 +558,48 @@
         }
         notifIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
+        // Send the share intent...
+        context.startActivity(notifIntent);
+
+        // ... and stop watching this process.
+        stopProgress(pid);
+    }
+
+    /**
+     * Sends a notitication indicating the bugreport has finished so use can share it.
+     */
+    private static void sendBugreportNotification(Context context, BugreportInfo info) {
+        final Intent shareIntent = new Intent(INTENT_BUGREPORT_SHARE);
+        shareIntent.setClass(context, BugreportProgressService.class);
+        shareIntent.setAction(INTENT_BUGREPORT_SHARE);
+        shareIntent.putExtra(EXTRA_PID, info.pid);
+
         final String title = context.getString(R.string.bugreport_finished_title);
         final Notification.Builder builder = new Notification.Builder(context)
                 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
                 .setContentTitle(title)
                 .setTicker(title)
                 .setContentText(context.getString(R.string.bugreport_finished_text))
-                .setContentIntent(PendingIntent.getActivity(
-                        context, 0, notifIntent, PendingIntent.FLAG_CANCEL_CURRENT))
-                .setAutoCancel(true)
+                .setContentIntent(PendingIntent.getService(context, 0, shareIntent,
+                        PendingIntent.FLAG_CANCEL_CURRENT))
+                .setDeleteIntent(newCancelIntent(context, info))
                 .setLocalOnly(true)
                 .setColor(context.getColor(
                         com.android.internal.R.color.system_notification_accent_color));
 
-        NotificationManager.from(context).notify(TAG, pid, builder.build());
+        NotificationManager.from(context).notify(TAG, info.pid, builder.build());
     }
 
     /**
      * Sends a zipped bugreport notification.
      */
     private static void sendZippedBugreportNotification(final Context context,
-            final int pid, final File bugreportFile, final File screenshotFile) {
+            final BugreportInfo info) {
         new AsyncTask<Void, Void, Void>() {
             @Override
             protected Void doInBackground(Void... params) {
-                File zippedFile = zipBugreport(bugreportFile);
-                sendBugreportNotification(context, pid, zippedFile, screenshotFile);
+                info.bugreportFile = zipBugreport(info.bugreportFile);
+                sendBugreportNotification(context, info);
                 return null;
             }
         }.execute();
@@ -629,31 +685,31 @@
     }
 
     /**
-     * Information about a bug report process while its in progress.
+     * Information about a bugreport process while its in progress.
      */
     private static final class BugreportInfo {
         private final Context context;
 
         /**
-         * {@code pid} of the {@code dumpstate} process generating the bug report.
+         * {@code pid} of the {@code dumpstate} process generating the bugreport.
          */
         final int pid;
 
         /**
-         * Name of the bug report, will be used to rename the final files.
+         * Name of the bugreport, will be used to rename the final files.
          * <p>
-         * Initial value is the bug report filename reported by {@code dumpstate}, but user can
+         * Initial value is the bugreport filename reported by {@code dumpstate}, but user can
          * change it later to a more meaningful name.
          */
         String name;
 
         /**
-         * Maximum progress of the bug report generation.
+         * Maximum progress of the bugreport generation.
          */
         int max;
 
         /**
-         * Current progress of the bug report generation.
+         * Current progress of the bugreport generation.
          */
         int progress;
 
@@ -662,6 +718,24 @@
          */
         long lastUpdate = System.currentTimeMillis();
 
+        /**
+         * Path of the main bugreport file.
+         */
+        File bugreportFile;
+
+        /**
+         * Path of the screenshot file.
+         */
+        File screenshotFile;
+
+        /**
+         * Whether dumpstate sent an intent informing it has finished.
+         */
+        boolean finished;
+
+        /**
+         * Constructor for tracked bugreports - typically called upon receiving BUGREPORT_STARTED.
+         */
         BugreportInfo(Context context, int pid, String name, int max) {
             this.context = context;
             this.pid = pid;
@@ -669,6 +743,15 @@
             this.max = max;
         }
 
+        /**
+         * Constructor for untracked bugreports - typically called upon receiving BUGREPORT_FINISHED
+         * without a previous call to BUGREPORT_STARTED.
+         */
+        BugreportInfo(Context context, int pid) {
+            this(context, pid, null, 0);
+            this.finished = true;
+        }
+
         String getFormattedLastUpdate() {
             return DateUtils.formatDateTime(context, lastUpdate,
                     DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME);
@@ -677,8 +760,10 @@
         @Override
         public String toString() {
             final float percent = ((float) progress * 100 / max);
-            return "Progress for " + name + " (pid=" + pid + "): " + progress + "/" + max
-                    + " (" + percent + "%) Last update: " + getFormattedLastUpdate();
+            return "pid: " + pid + ", name: " + name + ", finished: " + finished
+                    + "\n\tfile: " + bugreportFile + "\n\tscreenshot: " + screenshotFile
+                    + "\n\tprogress: " + progress + "/" + max + "(" + percent + ")"
+                    + "\n\tlast_update: " + getFormattedLastUpdate();
         }
     }
 }
diff --git a/packages/Shell/src/com/android/shell/BugreportReceiver.java b/packages/Shell/src/com/android/shell/BugreportReceiver.java
index 5133162..b818343 100644
--- a/packages/Shell/src/com/android/shell/BugreportReceiver.java
+++ b/packages/Shell/src/com/android/shell/BugreportReceiver.java
@@ -19,6 +19,7 @@
 import static com.android.shell.BugreportProgressService.EXTRA_BUGREPORT;
 import static com.android.shell.BugreportProgressService.EXTRA_ORIGINAL_INTENT;
 import static com.android.shell.BugreportProgressService.INTENT_BUGREPORT_FINISHED;
+import static com.android.shell.BugreportProgressService.TAG;
 import static com.android.shell.BugreportProgressService.getFileExtra;
 
 import java.io.File;
@@ -29,6 +30,7 @@
 import android.os.AsyncTask;
 import android.os.FileUtils;
 import android.text.format.DateUtils;
+import android.util.Log;
 
 /**
  * Receiver that handles finished bugreports, usually by attaching them to an
@@ -63,6 +65,10 @@
             return;
         }
         final File bugreportFile = getFileExtra(intent, EXTRA_BUGREPORT);
+        if (bugreportFile == null || !bugreportFile.exists()) {
+            Log.e(TAG, "Not deleting old files because file " + bugreportFile + " doesn't exist");
+            return;
+        }
         final PendingResult result = goAsync();
         new AsyncTask<Void, Void, Void>() {
             @Override
diff --git a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
index a54d9ef..6b6b0da 100644
--- a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
+++ b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
@@ -29,6 +29,7 @@
 import java.io.BufferedOutputStream;
 import java.io.BufferedWriter;
 import java.io.ByteArrayOutputStream;
+import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -40,16 +41,21 @@
 import java.util.zip.ZipOutputStream;
 
 import libcore.io.Streams;
+import android.app.ActivityManager;
+import android.app.ActivityManager.RunningServiceInfo;
 import android.app.Instrumentation;
 import android.app.NotificationManager;
 import android.content.Context;
+import android.content.ContextWrapper;
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.SystemProperties;
 import android.service.notification.StatusBarNotification;
 import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject;
 import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
 
 import com.android.shell.ActionSendMultipleConsumerActivity.CustomActionSendMultipleListener;
@@ -68,26 +74,28 @@
  * <li>asserts the extras received by the custom activity
  * </ul>
  * <p>
- * TODO: currently, these tests only work if the bug report sharing warning is disabled and the
- * device screen is unlocked.
+ * <strong>NOTE</strong>: these tests only work if the device is unlocked.
  */
+@LargeTest
 public class BugreportReceiverTest extends InstrumentationTestCase {
 
     private static final String TAG = "BugreportReceiverTest";
 
     // Timeout for UI operations, in milliseconds.
-    private static final int TIMEOUT = 1000;
+    private static final int TIMEOUT = (int) BugreportProgressService.POLLING_FREQUENCY * 4;
 
-    private static final String ROOT_DIR = "/data/data/com.android.shell/files/bugreports";
+    private static final String BUGREPORTS_DIR = "bugreports";
     private static final String BUGREPORT_FILE = "test_bugreport.txt";
     private static final String ZIP_FILE = "test_bugreport.zip";
-    private static final String PLAIN_TEXT_PATH = ROOT_DIR + "/" + BUGREPORT_FILE;
-    private static final String ZIP_PATH = ROOT_DIR + "/" + ZIP_FILE;
-    private static final String SCREENSHOT_PATH = ROOT_DIR + "/test_screenshot.png";
+    private static final String SCREENSHOT_FILE = "test_screenshot.png";
 
     private static final String BUGREPORT_CONTENT = "Dump, might as well dump!\n";
     private static final String SCREENSHOT_CONTENT = "A picture is worth a thousand words!\n";
 
+    private String mPlainTextPath;
+    private String mZipPath;
+    private String mScreenshotPath;
+
     private Context mContext;
     private UiBot mUiBot;
     private CustomActionSendMultipleListener mListener;
@@ -98,7 +106,11 @@
         mContext = instrumentation.getTargetContext();
         mUiBot = new UiBot(UiDevice.getInstance(instrumentation), TIMEOUT);
         mListener = ActionSendMultipleConsumerActivity.getListener(mContext);
+        mPlainTextPath = getPath(BUGREPORT_FILE);
+        mZipPath = getPath(ZIP_FILE);
+        mScreenshotPath = getPath(SCREENSHOT_FILE);
         cancelExistingNotifications();
+        BugreportPrefs.setWarningState(mContext, BugreportPrefs.STATE_HIDE);
     }
 
     public void testFullWorkflow() throws Exception {
@@ -124,37 +136,68 @@
         SystemProperties.set("dumpstate.42.max", "2000");
         assertProgressNotification(name, "25.00%");
 
-        createTextFile(PLAIN_TEXT_PATH, BUGREPORT_CONTENT);
-        createTextFile(SCREENSHOT_PATH, SCREENSHOT_CONTENT);
-        Bundle extras = sendBugreportFinishedIntent(42, PLAIN_TEXT_PATH, SCREENSHOT_PATH);
+        createTextFile(mPlainTextPath, BUGREPORT_CONTENT);
+        createTextFile(mScreenshotPath, SCREENSHOT_CONTENT);
+        Bundle extras = sendBugreportFinishedIntent(42, mPlainTextPath, mScreenshotPath);
         assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT);
 
-        // TODO: assert service is down
+        String service = BugreportProgressService.class.getName();
+        assertFalse("Service '" + service + "' is still running", isServiceRunning(service));
+    }
+
+    public void testBugreportFinished_withWarning() throws Exception {
+        // Explicitly shows the warning.
+        BugreportPrefs.setWarningState(mContext, BugreportPrefs.STATE_SHOW);
+
+        // Send notification and click on share.
+        createTextFile(mPlainTextPath, BUGREPORT_CONTENT);
+        Intent intent = new Intent(INTENT_BUGREPORT_FINISHED);
+        intent.putExtra(EXTRA_BUGREPORT, mPlainTextPath);
+        mContext.sendBroadcast(intent);
+        mUiBot.clickOnNotification(mContext.getString(R.string.bugreport_finished_title));
+
+        // Handle the warning
+        mUiBot.getVisibleObject(mContext.getString(R.string.bugreport_confirm));
+        // TODO: get ok and showMessageAgain from the dialog reference above
+        UiObject showMessageAgain =
+                mUiBot.getVisibleObject(mContext.getString(R.string.bugreport_confirm_repeat));
+        mUiBot.click(showMessageAgain, "show-message-again");
+        UiObject ok = mUiBot.getVisibleObject(mContext.getString(com.android.internal.R.string.ok));
+        mUiBot.click(ok, "ok");
+
+        // Share the bugreport.
+        mUiBot.chooseActivity(UI_NAME);
+        Bundle extras = mListener.getExtras();
+        assertActionSendMultiple(extras, BUGREPORT_CONTENT, null);
+
+        // Make sure it's hidden now.
+        int newState = BugreportPrefs.getWarningState(mContext, BugreportPrefs.STATE_UNKNOWN);
+        assertEquals("Didn't change state", BugreportPrefs.STATE_HIDE, newState);
     }
 
     public void testBugreportFinished_plainBugreportAndScreenshot() throws Exception {
-        createTextFile(PLAIN_TEXT_PATH, BUGREPORT_CONTENT);
-        createTextFile(SCREENSHOT_PATH, SCREENSHOT_CONTENT);
-        Bundle extras = sendBugreportFinishedIntent(PLAIN_TEXT_PATH, SCREENSHOT_PATH);
+        createTextFile(mPlainTextPath, BUGREPORT_CONTENT);
+        createTextFile(mScreenshotPath, SCREENSHOT_CONTENT);
+        Bundle extras = sendBugreportFinishedIntent(mPlainTextPath, mScreenshotPath);
         assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT);
     }
 
     public void testBugreportFinished_zippedBugreportAndScreenshot() throws Exception {
-        createZipFile(ZIP_PATH, BUGREPORT_FILE, BUGREPORT_CONTENT);
-        createTextFile(SCREENSHOT_PATH, SCREENSHOT_CONTENT);
-        Bundle extras = sendBugreportFinishedIntent(ZIP_PATH, SCREENSHOT_PATH);
+        createZipFile(mZipPath, BUGREPORT_FILE, BUGREPORT_CONTENT);
+        createTextFile(mScreenshotPath, SCREENSHOT_CONTENT);
+        Bundle extras = sendBugreportFinishedIntent(mZipPath, mScreenshotPath);
         assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT);
     }
 
     public void testBugreportFinished_plainBugreportAndNoScreenshot() throws Exception {
-        createTextFile(PLAIN_TEXT_PATH, BUGREPORT_CONTENT);
-        Bundle extras = sendBugreportFinishedIntent(PLAIN_TEXT_PATH, null);
+        createTextFile(mPlainTextPath, BUGREPORT_CONTENT);
+        Bundle extras = sendBugreportFinishedIntent(mPlainTextPath, null);
         assertActionSendMultiple(extras, BUGREPORT_CONTENT, null);
     }
 
     public void testBugreportFinished_zippedBugreportAndNoScreenshot() throws Exception {
-        createZipFile(ZIP_PATH, BUGREPORT_FILE, BUGREPORT_CONTENT);
-        Bundle extras = sendBugreportFinishedIntent(ZIP_PATH, null);
+        createZipFile(mZipPath, BUGREPORT_FILE, BUGREPORT_CONTENT);
+        Bundle extras = sendBugreportFinishedIntent(mZipPath, null);
         assertActionSendMultiple(extras, BUGREPORT_CONTENT, null);
     }
 
@@ -275,6 +318,17 @@
         fail("Did not find entry '" + entryName + "' on file '" + uri + "'");
     }
 
+    private boolean isServiceRunning(String name) {
+        ActivityManager manager = (ActivityManager) mContext
+                .getSystemService(Context.ACTIVITY_SERVICE);
+        for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
+            if (service.service.getClassName().equals(name)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private static void createTextFile(String path, String content) throws IOException {
         Log.v(TAG, "createFile(" + path + ")");
         try (Writer writer = new BufferedWriter(new OutputStreamWriter(
@@ -294,4 +348,12 @@
             zos.closeEntry();
         }
     }
+
+    private String getPath(String file) {
+        File rootDir = new ContextWrapper(mContext).getFilesDir();
+        File dir = new File(rootDir, BUGREPORTS_DIR);
+        String path = new File(dir, file).getAbsolutePath();
+        Log.v(TAG, "Path for '" + file + "': " + path);
+        return path;
+    }
 }
diff --git a/packages/Shell/tests/src/com/android/shell/UiBot.java b/packages/Shell/tests/src/com/android/shell/UiBot.java
index 5e8bab1..7d37137 100644
--- a/packages/Shell/tests/src/com/android/shell/UiBot.java
+++ b/packages/Shell/tests/src/com/android/shell/UiBot.java
@@ -118,7 +118,8 @@
     // TODO: UI Automator should provide such logic.
     public void chooseActivity(String name) {
         // First check if the activity is the default option.
-        String shareText = String.format("Share with %s", name);
+        String shareText = "Share with " + name;
+        Log.v(TAG, "Waiting for ActivityChooser text: '" + shareText + "'");
         boolean gotIt = mDevice.wait(Until.hasObject(By.text(shareText)), mTimeout);
 
         if (gotIt) {
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 2f79adf..51b84f5 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -136,6 +136,9 @@
             android:protectionLevel="signature" />
     <uses-permission android:name="com.android.systemui.permission.SELF" />
 
+    <!-- Adding Quick Settings tiles -->
+    <uses-permission android:name="android.permission.BIND_QUICK_SETTINGS_TILE" />
+
     <application
         android:name=".SystemUIApplication"
         android:persistent="true"
@@ -180,13 +183,6 @@
             </intent-filter>
         </receiver>
 
-        <receiver android:name=".qs.tiles.HotspotTile$APChangedReceiver"
-                androidprv:systemUserOnly="true">
-            <intent-filter>
-                <action android:name="android.net.wifi.WIFI_AP_STATE_CHANGED" />
-            </intent-filter>
-        </receiver>
-
         <activity android:name=".tuner.TunerActivity"
                   android:enabled="false"
                   android:icon="@drawable/tuner"
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_animation_cross_1.xml
new file mode 100644
index 0000000..661ab08
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_animation_cross_1.xml
@@ -0,0 +1,31 @@
+<?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="350"
+        android:propertyName="pathData"
+        android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+        android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+        android:valueType="pathType"
+        android:interpolator="@interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator" />
+    <objectAnimator
+        android:duration="17"
+        android:propertyName="strokeAlpha"
+        android:valueFrom="0"
+        android:valueTo="1"
+        android:interpolator="@android:interpolator/linear" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_animation_mask.xml
new file mode 100644
index 0000000..1199442
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_animation_mask.xml
@@ -0,0 +1,25 @@
+<?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="350"
+        android:propertyName="pathData"
+        android:valueFrom="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+        android:valueTo="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+        android:valueType="pathType"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_disable_animation_root.xml b/packages/SystemUI/res/anim/ic_signal_workmode_disable_animation_root.xml
new file mode 100644
index 0000000..72834c9
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_disable_animation_root.xml
@@ -0,0 +1,24 @@
+<?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="350"
+        android:propertyName="alpha"
+        android:valueFrom="1.0"
+        android:valueTo="0.3"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_cross_1.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_cross_1.xml
new file mode 100644
index 0000000..6c7e751
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_cross_1.xml
@@ -0,0 +1,40 @@
+<?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="350"
+        android:propertyName="pathData"
+        android:valueFrom="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+        android:valueTo="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+        android:valueType="pathType"
+        android:interpolator="@interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator" />
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="333"
+            android:propertyName="strokeAlpha"
+            android:valueFrom="1"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="17"
+            android:propertyName="strokeAlpha"
+            android:valueFrom="1"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_ic_signal_briefcase.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_ic_signal_briefcase.xml
new file mode 100644
index 0000000..c699fe2
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_ic_signal_briefcase.xml
@@ -0,0 +1,33 @@
+<?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="200"
+            android:propertyName="alpha"
+            android:valueFrom="0.5"
+            android:valueTo="0.5"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="alpha"
+            android:valueFrom="0.5"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/fast_out_slow_in" />
+    </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_mask.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_mask.xml
new file mode 100644
index 0000000..5595e5c
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_mask.xml
@@ -0,0 +1,25 @@
+<?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="350"
+        android:propertyName="pathData"
+        android:valueFrom="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+        android:valueTo="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z"
+        android:valueType="pathType"
+        android:interpolator="@interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator" />
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_root.xml b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_root.xml
new file mode 100644
index 0000000..85573e0
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_workmode_enable_animation_root.xml
@@ -0,0 +1,24 @@
+<?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="350"
+        android:propertyName="alpha"
+        android:valueFrom="0.3"
+        android:valueTo="1.0"
+        android:interpolator="@android:interpolator/fast_out_slow_in" />
+</set>
diff --git a/core/res/res/drawable/ic_arrow_up_14dp.xml b/packages/SystemUI/res/color/remote_input_send.xml
similarity index 60%
rename from core/res/res/drawable/ic_arrow_up_14dp.xml
rename to packages/SystemUI/res/color/remote_input_send.xml
index c4cc0d1..fe2ffaa 100644
--- a/core/res/res/drawable/ic_arrow_up_14dp.xml
+++ b/packages/SystemUI/res/color/remote_input_send.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
   ~ Copyright (C) 2015 The Android Open Source Project
   ~
@@ -13,12 +14,8 @@
   ~ 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:width="14.0dp"
-        android:height="14.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M12.000000,8.000000l-6.000000,6.000000 1.400000,1.400000 4.600000,-4.599999 4.600000,4.599999 1.400000,-1.400000z"
-        android:fillColor="#FF000000"/>
-</vector>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="true" android:color="@android:color/white" />
+    <item android:color="#4dffffff" /> <!-- 30% white -->
+</selector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_arrow_up_14dp.xml b/packages/SystemUI/res/color/remote_input_text.xml
similarity index 60%
copy from core/res/res/drawable/ic_arrow_up_14dp.xml
copy to packages/SystemUI/res/color/remote_input_text.xml
index c4cc0d1..11ce0b7 100644
--- a/core/res/res/drawable/ic_arrow_up_14dp.xml
+++ b/packages/SystemUI/res/color/remote_input_text.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
   ~ Copyright (C) 2015 The Android Open Source Project
   ~
@@ -13,12 +14,8 @@
   ~ 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:width="14.0dp"
-        android:height="14.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M12.000000,8.000000l-6.000000,6.000000 1.400000,1.400000 4.600000,-4.599999 4.600000,4.599999 1.400000,-1.400000z"
-        android:fillColor="#FF000000"/>
-</vector>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="true" android:color="@android:color/white" />
+    <item android:color="#99ffffff" /> <!-- 60% white -->
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/docked_divider_handle.xml b/packages/SystemUI/res/drawable/docked_divider_handle.xml
index ea32548..84c0343 100644
--- a/packages/SystemUI/res/drawable/docked_divider_handle.xml
+++ b/packages/SystemUI/res/drawable/docked_divider_handle.xml
@@ -17,6 +17,6 @@
         android:shape="rectangle">
     <size android:height="@dimen/docked_divider_handle_height"
         android:width="@dimen/docked_divider_handle_width" />
-    <corners radius="1dp" />
+    <corners android:radius="1dp" />
     <solid android:color="@color/docked_divider_handle" />
 </shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/header_dot.xml b/packages/SystemUI/res/drawable/header_dot.xml
new file mode 100644
index 0000000..568a9c2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/header_dot.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+** Copyright 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.
+-->
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval">
+
+    <solid 
+        android:color="#FFFFFF"/>
+
+    <size 
+        android:width="3dp"
+        android:height="3dp"/>
+</shape>
diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_disable.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_disable.xml
new file mode 100644
index 0000000..1feb49c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_workmode_disable.xml
@@ -0,0 +1,64 @@
+<?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="root"
+    android:alpha="1.0"
+    android:height="42dp"
+    android:width="42dp"
+    android:viewportHeight="42"
+    android:viewportWidth="42" >
+    <group
+        android:name="ic_signal_briefcase"
+        android:translateX="21.9995"
+        android:translateY="25.73401" >
+        <group
+            android:name="ic_signal_briefcase_pivot"
+            android:translateX="-23.21545"
+            android:translateY="-18.86649" >
+            <clip-path
+                android:name="mask"
+                android:pathData="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
+            <group
+                android:name="cross" >
+                <path
+                    android:name="cross_1"
+                    android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
+                    android:strokeColor="#FFFFFFFF"
+                    android:strokeAlpha="0"
+                    android:strokeWidth="3.5"
+                    android:fillColor="#00000000" />
+            </group>
+            <group
+                android:name="briefcase"
+                android:translateX="23.481"
+                android:translateY="18.71151" >
+                <path
+                    android:fillColor="#FFFFFFFF"
+                    android:fillAlpha="1"
+                    android:pathData="M-4.83333,-14.3333 L-7.16667,-11.8333 L-7.16667,-9.5 L-4.83333,-9.5 L-4.83333,-11.8333 L4.83333,-11.8333 L4.83333,-9.5 L7.16667,-9.5 L7.16667,-11.8333 L4.83333,-14.3333 Z" />
+                <path
+                    android:fillColor="#FFFFFFFF"
+                    android:fillAlpha="1"
+                    android:pathData="M13.1667,-9.5 L-13.1667,-9.5 C-14.5,-9.5,-15.5,-8.5,-15.5,-7.16666 L-15.5,0.00000286102 C-15.5,1.33334,-14.5,2.33334,-13.1667,2.33334 L-3.66667,2.33334 L-3.66667,0.00000286102 L3.5,0.00000286102 L3.5,2.33334 L13,2.33334 C14.3333,2.33334,15.3333,1.33334,15.3333,0 L15.3333,-7.16666 C15.5,-8.5,14.3333,-9.5,13.1667,-9.5 Z" />
+                <path
+                    android:fillColor="#FFFFFFFF"
+                    android:fillAlpha="1"
+                    android:pathData="M-3.5,7.16667 L-3.5,4.83334 L-14.3333,4.83334 L-14.3333,10.8333 C-14.3333,12.1667,-13.3333,13.1667,-12,13.1667 L11.8333,13.1667 C13.1667,13.1667,14.1667,12.1667,14.1667,10.8333 L14.1667,4.83334 L3.5,4.83334 L3.5,7.16667 L-3.5,7.16667 Z" />
+            </group>
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_disable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_disable_animation.xml
new file mode 100644
index 0000000..a15a127
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_workmode_disable_animation.xml
@@ -0,0 +1,28 @@
+<?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/ic_signal_workmode_disable" >
+    <target
+        android:name="root"
+        android:animation="@anim/ic_signal_workmode_disable_animation_root" />
+    <target
+        android:name="mask"
+        android:animation="@anim/ic_signal_workmode_disable_animation_mask" />
+    <target
+        android:name="cross_1"
+        android:animation="@anim/ic_signal_workmode_disable_animation_cross_1" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_enable.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_enable.xml
new file mode 100644
index 0000000..ad14505
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_workmode_enable.xml
@@ -0,0 +1,64 @@
+<?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="root"
+    android:alpha="0.3"
+    android:height="42dp"
+    android:width="42dp"
+    android:viewportHeight="42"
+    android:viewportWidth="42" >
+    <group
+        android:name="ic_signal_briefcase"
+        android:translateX="21.9995"
+        android:translateY="25.73401" >
+        <group
+            android:name="ic_signal_briefcase_pivot"
+            android:translateX="-23.21545"
+            android:translateY="-18.86649" >
+            <clip-path
+                android:name="mask"
+                android:pathData="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
+            <group
+                android:name="cross" >
+                <path
+                    android:name="cross_1"
+                    android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+                    android:strokeColor="#FFFFFFFF"
+                    android:strokeAlpha="1"
+                    android:strokeWidth="3.5"
+                    android:fillColor="#00000000" />
+            </group>
+            <group
+                android:name="briefcase"
+                android:translateX="23.481"
+                android:translateY="18.71151" >
+                <path
+                    android:fillColor="#FFFFFFFF"
+                    android:fillAlpha="1"
+                    android:pathData="M-4.83333,-14.3333 L-7.16667,-11.8333 L-7.16667,-9.5 L-4.83333,-9.5 L-4.83333,-11.8333 L4.83333,-11.8333 L4.83333,-9.5 L7.16667,-9.5 L7.16667,-11.8333 L4.83333,-14.3333 Z" />
+                <path
+                    android:fillColor="#FFFFFFFF"
+                    android:fillAlpha="1"
+                    android:pathData="M13.1667,-9.5 L-13.1667,-9.5 C-14.5,-9.5,-15.5,-8.5,-15.5,-7.16666 L-15.5,0.00000286102 C-15.5,1.33334,-14.5,2.33334,-13.1667,2.33334 L-3.66667,2.33334 L-3.66667,0.00000286102 L3.5,0.00000286102 L3.5,2.33334 L13,2.33334 C14.3333,2.33334,15.3333,1.33334,15.3333,0 L15.3333,-7.16666 C15.5,-8.5,14.3333,-9.5,13.1667,-9.5 Z" />
+                <path
+                    android:fillColor="#FFFFFFFF"
+                    android:fillAlpha="1"
+                    android:pathData="M-3.5,7.16667 L-3.5,4.83334 L-14.3333,4.83334 L-14.3333,10.8333 C-14.3333,12.1667,-13.3333,13.1667,-12,13.1667 L11.8333,13.1667 C13.1667,13.1667,14.1667,12.1667,14.1667,10.8333 L14.1667,4.83334 L3.5,4.83334 L3.5,7.16667 L-3.5,7.16667 Z" />
+            </group>
+        </group>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_workmode_enable_animation.xml b/packages/SystemUI/res/drawable/ic_signal_workmode_enable_animation.xml
new file mode 100644
index 0000000..41d2b42
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_workmode_enable_animation.xml
@@ -0,0 +1,31 @@
+<?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/ic_signal_workmode_enable" >
+    <target
+        android:name="root"
+        android:animation="@anim/ic_signal_workmode_enable_animation_root" />
+    <target
+        android:name="ic_signal_briefcase"
+        android:animation="@anim/ic_signal_workmode_enable_animation_ic_signal_briefcase" />
+    <target
+        android:name="mask"
+        android:animation="@anim/ic_signal_workmode_enable_animation_mask" />
+    <target
+        android:name="cross_1"
+        android:animation="@anim/ic_signal_workmode_enable_animation_cross_1" />
+</animated-vector>
diff --git a/core/res/res/drawable/ic_arrow_up_14dp.xml b/packages/SystemUI/res/drawable/quick_header_bg.xml
similarity index 60%
copy from core/res/res/drawable/ic_arrow_up_14dp.xml
copy to packages/SystemUI/res/drawable/quick_header_bg.xml
index c4cc0d1..d45d673 100644
--- a/core/res/res/drawable/ic_arrow_up_14dp.xml
+++ b/packages/SystemUI/res/drawable/quick_header_bg.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
   ~ Copyright (C) 2015 The Android Open Source Project
   ~
@@ -13,12 +14,8 @@
   ~ 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:width="14.0dp"
-        android:height="14.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:pathData="M12.000000,8.000000l-6.000000,6.000000 1.400000,1.400000 4.600000,-4.599999 4.600000,4.599999 1.400000,-1.400000z"
-        android:fillColor="#FF000000"/>
-</vector>
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="?android:attr/colorControlHighlight" >
+    <item android:drawable="@color/system_primary_color"/>
+</ripple>
diff --git a/packages/SystemUI/res/drawable/recents_freeform_workspace_bg.xml b/packages/SystemUI/res/drawable/recents_freeform_workspace_bg.xml
new file mode 100644
index 0000000..5f9341c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/recents_freeform_workspace_bg.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <corners android:topLeftRadius="@dimen/recents_task_view_rounded_corners_radius"
+             android:topRightRadius="@dimen/recents_task_view_rounded_corners_radius"/>
+    <solid android:color="#00000000" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/stat_sys_managed_profile_disable_animation.xml b/packages/SystemUI/res/drawable/stat_sys_managed_profile_disable_animation.xml
new file mode 100644
index 0000000..c6a2fdd
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_managed_profile_disable_animation.xml
@@ -0,0 +1,47 @@
+<!--
+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:width="27.0dp"
+        android:height="22.0dp"
+        android:alpha="0.3"
+        android:viewportWidth="27.0"
+        android:viewportHeight="22.0">
+    <clip-path
+        android:name="mask"
+        android:pathData="M 38.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,41.1153411865 40.9884796143,41.1153411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-41.1267852783 -41.1884460449,-41.1267852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
+    <group
+        android:name="cross" >
+        <path
+            android:name="cross_1"
+            android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
+            android:strokeColor="#FFFFFFFF"
+            android:strokeAlpha="1"
+            android:strokeWidth="3.5"
+            android:fillColor="#00000000" />
+    </group>
+    <group
+        android:name="work_badge"
+        android:translateX="3.0"
+        android:scaleX="1.4"
+        android:scaleY="1.4">
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M9.9,11.6H7v-1.1H2.1v2.8c0,0.8,0.6,1.4,1.4,1.4h9.9c0.8,0,1.4,-0.6,1.4,-1.4v-2.8H9.9V11.6z"/>
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M14.1,4.2h-2.5V3.2l-1.1,-1.1H6.3L5.3,3.2v1H2.8C2,4.2,1.4,4.9,1.4,5.6v2.8c0,0.8,0.6,1.4,1.4,1.4H7V8.8h2.8v1.1h4.2     c0.8,0,1.4,-0.6,1.4,-1.4V5.6C15.5,4.9,14.8,4.2,14.1,4.2z M10.6,4.2H6.3V3.2h4.2V4.2z"/>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_managed_profile_enable_animation.xml b/packages/SystemUI/res/drawable/stat_sys_managed_profile_enable_animation.xml
new file mode 100644
index 0000000..d67c89ac
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_managed_profile_enable_animation.xml
@@ -0,0 +1,34 @@
+<!--
+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:width="27.0dp"
+        android:height="22.0dp"
+        android:alpha="1.0"
+        android:viewportWidth="27.0"
+        android:viewportHeight="22.0">
+    <group
+        android:name="work_badge"
+        android:translateX="3.0"
+        android:scaleX="1.4"
+        android:scaleY="1.4">
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M9.9,11.6H7v-1.1H2.1v2.8c0,0.8,0.6,1.4,1.4,1.4h9.9c0.8,0,1.4,-0.6,1.4,-1.4v-2.8H9.9V11.6z"/>
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M14.1,4.2h-2.5V3.2l-1.1,-1.1H6.3L5.3,3.2v1H2.8C2,4.2,1.4,4.9,1.4,5.6v2.8c0,0.8,0.6,1.4,1.4,1.4H7V8.8h2.8v1.1h4.2     c0.8,0,1.4,-0.6,1.4,-1.4V5.6C15.5,4.9,14.8,4.2,14.1,4.2z M10.6,4.2H6.3V3.2h4.2V4.2z"/>
+    </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml
index 2bfa39d..370f89c 100644
--- a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml
@@ -14,16 +14,29 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="23.0dp"
-        android:height="18.0dp"
-        android:viewportWidth="21.0"
-        android:viewportHeight="17.0">
-    <group android:translateX="2.0">
-        <path
-            android:fillColor="@android:color/white"
-            android:pathData="M9.9,11.6H7v-1.1H2.1v2.8c0,0.8,0.6,1.4,1.4,1.4h9.9c0.8,0,1.4,-0.6,1.4,-1.4v-2.8H9.9V11.6z"/>
-        <path
-            android:fillColor="@android:color/white"
-            android:pathData="M14.1,4.2h-2.5V3.2l-1.1,-1.1H6.3L5.3,3.2v1H2.8C2,4.2,1.4,4.9,1.4,5.6v2.8c0,0.8,0.6,1.4,1.4,1.4H7V8.8h2.8v1.1h4.2     c0.8,0,1.4,-0.6,1.4,-1.4V5.6C15.5,4.9,14.8,4.2,14.1,4.2z M10.6,4.2H6.3V3.2h4.2V4.2z"/>
-    </group>
+    android:width="23dp"
+    android:height="18dp"
+    android:viewportWidth="23"
+    android:viewportHeight="18">
+<!--
+    The asset contains a briefcase symbol of 15.26dp x 13.6dp in the center.
+-->
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M15.0815,4.5903 L15.0815,3.43636 L13.9276,2.2 L9.14696,2.2 L7.99302,3.43636
+L7.99302,4.5903 L9.14696,4.5903 L9.14696,3.43636 L13.9276,3.43636
+L13.9276,4.5903 Z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M18.0488,4.5903 L5.02575,4.5903 C4.36635,4.5903,3.87181,5.08485,3.87181,5.74424
+L3.87181,9.28848 C3.87181,9.94788,4.36635,10.4424,5.02575,10.4424
+L9.72393,10.4424 L9.72393,9.28848 L13.2682,9.28848 L13.2682,10.4424
+L17.9664,10.4424 C18.6257,10.4424,19.1203,9.94788,19.1203,9.28848
+L19.1203,5.74424 C19.2027,5.08485,18.6257,4.5903,18.0488,4.5903 Z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M9.80635,12.8327 L9.80635,11.6788 L4.44878,11.6788 L4.44878,14.6461
+C4.44878,15.3055,4.94332,15.8,5.60272,15.8 L17.3894,15.8
+C18.0488,15.8,18.5433,15.3055,18.5433,14.6461 L18.5433,11.6788 L13.2682,11.6788
+L13.2682,12.8327 L9.80635,12.8327 Z" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status_off.xml b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status_off.xml
new file mode 100644
index 0000000..35602b6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status_off.xml
@@ -0,0 +1,53 @@
+<!--
+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:width="23dp"
+    android:height="18dp"
+    android:viewportWidth="23"
+    android:viewportHeight="18">
+<!--
+    The asset contains a briefcase symbol of 15.26dp x 13.6dp in the center.
+-->
+    <path
+        android:pathData="M0,-6 L24,-6 L24,18 L0,18 L0,-6 Z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M13.9892,11.6542 L13.4088,11.6542 L13.4088,12.8152 L9.843,12.8152 L9.843,11.6542
+L4.4529,11.6542 L4.4529,14.6395 C4.4529,15.3029,4.95045,15.8005,5.61384,15.8005
+L17.4721,15.8005 C17.6379,15.8005,17.8038,15.8005,17.9696,15.7175
+L13.9892,11.6542 Z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M18.7159,13.8932 L18.7159,11.6542 L16.477,11.6542
+C17.3062,12.4835,18.1355,13.3127,18.7159,13.8932 Z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M6.85771,4.52272 L5.03337,4.52272
+C4.36998,4.52272,3.87243,5.02027,3.87243,5.68366 L3.87243,9.24942
+C3.87243,9.91282,4.36998,10.4104,5.03337,10.4104 L9.76008,10.4104
+L9.76008,9.24942 L11.5844,9.24942 L6.85771,4.52272 Z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M9.1796,4.35687 L9.1796,3.36177 L13.9063,3.36177 L13.9063,4.52272
+L9.34545,4.52272 C11.1698,6.34706,13.3258,8.5031,15.2331,10.4104
+L18.0525,10.4104 C18.7159,10.4104,19.2135,9.91282,19.2135,9.24942
+L19.2135,5.68366 C19.2135,5.02027,18.7159,4.52272,18.0525,4.52272
+L15.0673,4.52272 L15.0673,3.36177 L13.9063,2.20083 L9.1796,2.20083
+L8.10158,3.27885 C8.43328,3.61055,8.84791,4.02517,9.1796,4.35687 Z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M3.281,3.42136 L4.51236,2.19 L18.585,16.2626 L17.3536,17.494 L3.281,3.42136 Z" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator.xml
new file mode 100644
index 0000000..66cfaff
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_disable_cross_1_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?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 c 0.166666667,0 0.2,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator.xml
new file mode 100644
index 0000000..a0118d70
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_cross_1_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?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 c 0.8,0 0.833333333,1 1,1" />
diff --git a/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator.xml b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator.xml
new file mode 100644
index 0000000..1820bab
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_signal_workmode_enable_mask_pathdata_interpolator.xml
@@ -0,0 +1,18 @@
+<?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 c 0.8,0 0.6,1 1,1" />
diff --git a/packages/SystemUI/res/layout/docked_stack_divider.xml b/packages/SystemUI/res/layout/docked_stack_divider.xml
index 5f42856..22ed216 100644
--- a/packages/SystemUI/res/layout/docked_stack_divider.xml
+++ b/packages/SystemUI/res/layout/docked_stack_divider.xml
@@ -27,8 +27,6 @@
     <ImageButton
         style="@style/DockedDividerHandle"
         android:id="@+id/docked_divider_handle"
-        android:layout_height="48dp"
-        android:layout_width="48dp"
         android:background="@null"
         android:src="@drawable/docked_divider_handle"/>
 
diff --git a/packages/SystemUI/res/layout/hybrid_notification.xml b/packages/SystemUI/res/layout/hybrid_notification.xml
index 9e64d2c..f667859 100644
--- a/packages/SystemUI/res/layout/hybrid_notification.xml
+++ b/packages/SystemUI/res/layout/hybrid_notification.xml
@@ -18,21 +18,23 @@
 <com.android.systemui.statusbar.notification.HybridNotificationView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="@dimen/notification_max_height">
+    android:layout_height="wrap_content"
+    android:paddingStart="@*android:dimen/notification_content_margin_start"
+    android:paddingEnd="12dp"
+    android:gravity="bottom">
     <TextView
         android:id="@+id/notification_title"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_gravity="center_vertical"
+        android:paddingEnd="4dp"
         android:singleLine="true"
         android:textAppearance="@*android:style/TextAppearance.Material.Notification.Title"
-        android:paddingEnd="4dp"
     />
     <TextView
         android:id="@+id/notification_text"
-        android:layout_width="wrap_content"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_gravity="center_vertical"
+        android:paddingEnd="4dp"
         android:textAppearance="@*android:style/TextAppearance.Material.Notification"
         android:singleLine="true"
         />
diff --git a/packages/SystemUI/res/layout/notification_children_divider.xml b/packages/SystemUI/res/layout/notification_children_divider.xml
index f011afe..53273cf 100644
--- a/packages/SystemUI/res/layout/notification_children_divider.xml
+++ b/packages/SystemUI/res/layout/notification_children_divider.xml
@@ -20,4 +20,4 @@
     android:id="@+id/notification_more_divider"
     android:layout_width="match_parent"
     android:layout_height="@dimen/notification_children_divider_height"
-    android:background="@*android:drawable/notification_template_divider" />
+    android:background="#61000000" />
diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml
index 1873168..bb37b83 100644
--- a/packages/SystemUI/res/layout/qs_panel.xml
+++ b/packages/SystemUI/res/layout/qs_panel.xml
@@ -19,7 +19,6 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:background="@drawable/qs_background_primary"
-        android:paddingTop="8dp"
         android:paddingBottom="8dp"
         android:elevation="2dp">
 
diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
index cc35c51c..a995ec7 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -25,21 +25,14 @@
     android:layout_gravity="@integer/notification_panel_layout_gravity"
     android:paddingStart="@dimen/notification_side_padding"
     android:paddingEnd="@dimen/notification_side_padding"
+    android:clipChildren="false"
+    android:clipToPadding="false"
     android:baselineAligned="false"
-    android:elevation="4dp"
-    android:background="@drawable/notification_header_bg"
+    android:background="@drawable/quick_header_bg"
     android:clickable="true"
     android:focusable="true"
     >
 
-    <com.android.systemui.qs.QuickQSPanel
-        android:id="@+id/quick_qs_panel"
-        android:background="#0000"
-        android:layout_width="144dp"
-        android:layout_height="match_parent"
-        android:layout_alignParentEnd="true"
-        android:layout_marginEnd="12dp" />
-
     <LinearLayout
         android:id="@+id/expanded_group"
         android:layout_width="wrap_content"
@@ -49,7 +42,8 @@
         android:clipToPadding="false"
         android:orientation="horizontal"
         android:layout_alignParentEnd="true"
-        android:layout_marginEnd="10dp">
+        android:layout_marginTop="30dp"
+        android:layout_marginEnd="16dp">
 
         <com.android.systemui.statusbar.AlphaOptimizedFrameLayout
             android:id="@+id/settings_button_container"
@@ -84,48 +78,76 @@
             android:tint="@android:color/white" />
     </LinearLayout>
 
-    <FrameLayout
-        android:id="@+id/date_group"
+    <TextView
+        android:id="@+id/header_emergency_calls_only"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        android:layout_alignParentStart="true"
+        android:layout_alignParentTop="true"
+        android:paddingStart="16dp"
+        android:paddingEnd="16dp"
+        android:paddingTop="8dp"
+        android:visibility="gone"
+        android:textAppearance="@style/TextAppearance.StatusBar.Expanded.EmergencyCallsOnly"
+        android:text="@*android:string/emergency_calls_only"
+        android:singleLine="true"
+        android:gravity="center_vertical" />
+
+    <LinearLayout
+        android:id="@+id/date_time_group"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginBottom="@dimen/clock_collapsed_bottom_margin"
-        android:layout_alignParentBottom="true">
-        <com.android.systemui.statusbar.policy.DateView android:id="@+id/date_collapsed"
+        android:layout_alignParentStart="true"
+        android:layout_alignParentTop="true"
+        android:orientation="horizontal">
+
+        <include layout="@layout/split_clock_view"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginStart="16dp"
+            android:layout_marginTop="2dp"
+            android:id="@+id/clock" />
+
+        <com.android.systemui.statusbar.policy.DateView
+            android:id="@+id/date"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="6dp"
+            android:layout_marginTop="8dp"
+            android:layout_alignParentTop="true"
+            android:drawableStart="@drawable/header_dot"
+            android:drawablePadding="6dp"
             android:singleLine="true"
+            android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock"
+            android:textSize="@dimen/qs_time_collapsed_size"
+            systemui:datePattern="@string/abbrev_wday_month_day_no_year_alarm" />
+
+        <com.android.systemui.statusbar.AlphaOptimizedButton
+            android:id="@+id/alarm_status"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentTop="true"
+            android:drawablePadding="6dp"
+            android:drawableStart="@drawable/ic_access_alarms_small"
+            android:textColor="#64ffffff"
             android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Date"
-            android:layout_below="@id/clock"
-            systemui:datePattern="@string/abbrev_wday_month_day_no_year_alarm"
-            />
-    </FrameLayout>
+            android:minHeight="36dp"
+            android:paddingStart="6dp"
+            android:background="?android:attr/selectableItemBackground"
+            android:visibility="gone" />
+    </LinearLayout>
 
-    <include layout="@layout/split_clock_view"
-        android:layout_width="wrap_content"
+    <com.android.systemui.qs.QuickQSPanel
+        android:id="@+id/quick_qs_panel"
+        android:background="#0000"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginStart="16dp"
-        android:layout_above="@id/date_group"
-        android:id="@+id/clock"
-        />
-
-    <com.android.systemui.statusbar.AlphaOptimizedButton android:id="@+id/alarm_status"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentBottom="true"
-        android:layout_toEndOf="@id/date_group"
-        android:layout_marginBottom="4dp"
-        android:drawablePadding="6dp"
-        android:drawableStart="@drawable/ic_access_alarms_small"
-        android:textColor="#64ffffff"
-        android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Date"
-        android:paddingEnd="6dp"
-        android:paddingStart="6dp"
-        android:paddingTop="16dp"
-        android:paddingBottom="16dp"
-        android:background="?android:attr/selectableItemBackground"
-        android:visibility="gone"
-        />
+        android:layout_marginTop="30dp"
+        android:layout_marginStart="8dp"
+        android:layout_marginEnd="8dp"
+        android:layout_alignParentEnd="true"
+        android:clipChildren="false"
+        android:clipToPadding="false" />
 
     <include
         android:id="@+id/qs_detail_header"
diff --git a/packages/SystemUI/res/layout/remote_input.xml b/packages/SystemUI/res/layout/remote_input.xml
index 74092c1..83cfc76 100644
--- a/packages/SystemUI/res/layout/remote_input.xml
+++ b/packages/SystemUI/res/layout/remote_input.xml
@@ -36,7 +36,8 @@
             android:paddingEnd="12dp"
             android:gravity="start|center_vertical"
             android:textAppearance="?android:attr/textAppearance"
-            android:textColor="#deffffff"
+            android:textColor="@color/remote_input_text"
+            android:textColorHint="@color/remote_input_hint"
             android:textSize="16sp"
             android:background="@null"
             android:singleLine="true"
@@ -58,8 +59,8 @@
                 android:paddingBottom="12dp"
                 android:id="@+id/remote_input_send"
                 android:src="@drawable/ic_send"
-                android:tint="@android:color/white"
-                android:tintMode="src_atop"
+                android:tint="@color/remote_input_send"
+                android:tintMode="src_in"
                 android:background="@drawable/ripple_drawable" />
 
         <ProgressBar
diff --git a/packages/SystemUI/res/layout/split_clock_view.xml b/packages/SystemUI/res/layout/split_clock_view.xml
index d1269da..ae5136f 100644
--- a/packages/SystemUI/res/layout/split_clock_view.xml
+++ b/packages/SystemUI/res/layout/split_clock_view.xml
@@ -27,6 +27,7 @@
         android:layout_height="wrap_content"
         android:singleLine="true"
         android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock"
+        android:textSize="@dimen/qs_time_collapsed_size"
         />
     <TextClock
         android:id="@+id/am_pm_view"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 7006d43..f3e7cfe 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Luitoestel stil."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Maak <xliff:g id="APP">%s</xliff:g> toe."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> verwerp."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Alle onlangse programme is toegemaak."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobiele warmkol afgeskakel."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobiele warmkol aangeskakel."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Uitsaai van skerm gestaak."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Skermhelderheid"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G-data is laat wag"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G-data is laat wag"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> gebruik"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g>-limiet"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> waarskuwing"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Jou onlangse skerms verskyn hier"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Programinligting"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"skermvaspen"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Weier"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is die volumedialoog"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Raak om die oorspronklike terug te stel."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Jy gebruik tans jou werkprofiel"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Stelsel-UI-ontvanger"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Wys persentasie van ingebedde battery"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 948c538..838a4eb 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"የስልክ ጥሪ ፀጥታ።"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> አስወግድ።"</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ተሰናብቷል::"</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"ሁሉም የቅርብ ጊዜ ማመልከቻዎች ተሰናብተዋል።"</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"የተንቀሳቃሽ ስልክ መገናኛ ነጥብ ጠፍቷል።"</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"የተንቀሳቃሽ ስልክ መገናኛ ነጥብ በርቷል።"</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"ማያ ገጽ መውሰድ ቆሟል።"</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"ብሩህነት ያሳዩ"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2ጂ-3ጂ ውሂብ ላፍታ ቆሟል"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4ጂ ውሂብ ላፍታ ቆሟል"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> ጥቅም ላይ ውሏል"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> ገደብ"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"የ<xliff:g id="DATA_LIMIT">%s</xliff:g> ማስጠንቀቂያ"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"የቅርብ ጊዜ ማያ ገጾችዎ እዚህ ይታያሉ"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"የመተግበሪያ መረጃ"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ማያ ገጽ መሰካት"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"ከልክል"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> የድምጽ መጠን መገናኛው ነው"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"የመጀመሪያውን ወደነበረበት ለመመለስ ይንኩ።"</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">"፣"</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"የስራ መገለጫዎን እየተጠቀሙ ነው"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"የስርዓት በይነገጽ መቃኛ"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"የተቀላቀለ የባትሪ አጠቃቀም መቶኛ አሳይ"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index e272364..2789ffa 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -165,6 +165,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"رنين صامت."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"إزالة <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"تمت إزالة <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"تم تجاهل كل التطبيقات المستخدمة مؤخرًا."</string>
@@ -216,6 +218,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"تم إيقاف نقطة اتصال الجوّال."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"تم تشغيل نقطة اتصال الجوّال."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"توقف إرسال الشاشة."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"سطوع الشاشة"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"بيانات شبكات الجيل الثاني والثالث متوقفة مؤقتًا"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"تم إيقاف بيانات شبكة الجيل الرابع مؤقتًا"</string>
@@ -293,6 +303,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> مستخدم"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"قيد <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"تحذير <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"تظهر شاشاتك المعروضة مؤخرًا هنا"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"معلومات التطبيق"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"تثبيت الشاشة"</string>
@@ -407,7 +419,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"رفض"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> هو مربع حوار مستوى الصوت"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"المس لاستعادة الإعداد الأصلي."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">"،"</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"أنت تستخدم ملفك الشخصي للعمل"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"أداة ضبط واجهة مستخدم النظام"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"عرض نسبة البطارية المدمجة"</string>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml
index 7f2a6b07..652f71c 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Zəngvuran səssiz."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> kənarlaşdırın."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> çıxarıldı."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Bütün son tətbiqlər kənarlaşdırıldı."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobil hotspot deaktivdir."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobil hotspot aktivdir."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Ekran yayımı dayandırıldı."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Display brightness"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G məlumatlarına fasilə verildi"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G məlumatlarına fasilə verildi"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> işlənib"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> limit"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> xəbərdarlığı"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Your recent screens appear here"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Tətbiq haqqında"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ekran sancağı"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Rədd et"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> proqramı səs səviyyəsi dialoqudur"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Orijinalı bərpa etmək üçün toxun."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"İş profilinizi istifadə edirsiniz"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Daxil batareya faizini göstərin"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 6ed2adb..0bbdbe9 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Звънът е заглушен."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Отхвърляне на <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Приложението <xliff:g id="APP">%s</xliff:g> е отхвърлено."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Всички скорошни приложения са отхвърлени."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Мобилната точка за достъп се изключи."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Мобилната точка за достъп се включи."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Предаването на съдържанието от екрана спря."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Яркост на екрана"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Данните от 2G – 3G са поставени на пауза"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Данните от 4G са поставени на пауза"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Използвано: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Ограничение от <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Предупреждение: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Скорошните ви екрани се показват тук"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Информация за приложението"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"фиксиране на екрана"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Отказване"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> изпълнява ролята на диалоговия прозорец за силата на звука"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Докоснете, за да възстановите оригинала."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Използвате служебния си потребителски профил"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Тунер на системния потребителски интерфейс"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Показване на процента на вградената батерия"</string>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml
index 20e2c35..e1c3d5e 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"রিং বাজানো বন্ধ করুন৷"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> খারিজ করুন।"</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> খারিজ করা হয়েছে৷"</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"সমস্ত সাম্প্রতিক অ্যাপ্লিকেশন খারিজ করা হয়েছে।"</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"মোবাইল হটস্পট বন্ধ হয়েছে।"</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"মোবাইল হটস্পট চালু হয়েছে।"</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"স্ক্রীন কাস্ট করা থেমেছে।"</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"প্রদর্শনের উজ্জ্বলতা"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G ডেটা বিরতি দেওয়া হয়েছে"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G ডেটা বিরতি দেওয়া হয়েছে"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> ব্যবহৃত হয়েছে"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"সীমা <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> সতর্কতা"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"আপনার সাম্প্রতিক স্ক্রীনগুলো এখানে দেখা যাবে"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"অ্যাপ্লিকেশানের তথ্য"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"স্ক্রীন পিন করা"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"প্রত্যাখ্যান করুন"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> হল ভলিউম ডায়লগ"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"আসলটি পুনঃস্থাপন করতে স্পর্শ করুন৷"</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"আপনি আপনার কাজের প্রোফাইল ব্যবহার করছেন"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"সিস্টেম UI টিউনার"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"এম্বেড করা ব্যাটারির শতকরা হার দেখায়"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 0bb4826..e361ed0 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Mode silenci."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Ignora <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"S\'ha omès <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"S\'han descartat totes les aplicacions recents."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"El punt d\'accés mòbil està desactivat."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"El punt d\'accés mòbil està activat."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"S\'ha aturat l\'emissió de la pantalla."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Brillantor de la pantalla"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Les dades 2G-3G estan aturades"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Les dades 4G estan aturades"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Utilitzats: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Límit: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Advertiment: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Aquí es mostren les teves pantalles recents."</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informació de l\'aplicació"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fixació de pantalla"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Denega"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> és el diàleg de volum"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Toca per restaurar l\'original."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Estàs utilitzant el perfil professional"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Personalitzador d\'interfície d\'usuari"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Mostra el percentatge de la bateria inserit"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 63a16ad..11a9bbe 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -163,6 +163,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Tiché vyzvánění."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Zavřít aplikaci <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Aplikace <xliff:g id="APP">%s</xliff:g> byla odebrána."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Všechny naposledy použité aplikace byly odstraněny."</string>
@@ -214,6 +216,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobile hotspot je vypnutý."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobile hotspot je zapnutý."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Odesílání obrazovky zastaveno."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Jas displeje"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Data 2G a 3G jsou pozastavena"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Data 4G jsou pozastavena"</string>
@@ -291,6 +301,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Využito: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Limit: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Upozornění při <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Zde budou zobrazeny vaše poslední obrazovky"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informace o aplikaci"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"připnutí obrazovky"</string>
@@ -405,7 +417,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Odmítnout"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> je dialog hlasitosti"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Klepnutím obnovíte originál."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Používáte pracovní profil"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Nástroj na ladění uživatelského rozhraní systému"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Zobrazovat vložené procento nabití baterie"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index eb8053d..aef1037 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Lydløs."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Afvis <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> er annulleret."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Alle de seneste applikationer er lukket."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobilhotspot er slået fra."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobilhotspot er slået til."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Casting af din skærm er stoppet."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Skærmens lysstyrke"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G-data er sat på pause"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G-data er sat på pause"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> brugt"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Grænse: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Advarsel ved <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Dine seneste skærme vises her"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Oplysninger om applikationen"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"bliv i app"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Afvis"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> er dialogboksen for lydstyrke"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Tryk for at gendanne originalen."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Du bruger din arbejdsprofil"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Vis procent for det indbyggede batteri"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index e156c92..6ba1a8e 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Klingelton lautlos"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> beenden"</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> entfernt"</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Alle kürzlich verwendeten Apps wurden entfernt."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Der mobile Hotspot ist deaktiviert."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Der mobile Hotspot ist aktiviert."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Die Bildschirmübertragung wurde angehalten."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Helligkeit des Displays"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-/3G-Daten pausiert"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G-Daten pausiert"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> verwendet"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> Datenlimit"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Warnung für <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Hier sehen Sie Ihre zuletzt geöffneten Apps."</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"App-Info"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"Bildschirmfixierung"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Ablehnen"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> regelt die Lautstärke."</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Zum Wiederherstellen des Originals hier tippen"</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">"u."</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Sie verwenden Ihr Arbeitsprofil."</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Eingebettete Akku-Prozentzahl anzeigen"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index b0dcc40..c9c7efb 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Ειδοποίηση ήχου στο αθόρυβο."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Παράβλεψη <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Απορρίφθηκαν <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Έγινε παράβλεψη όλων των πρόσφατων εφαρμογών."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Το σημείο πρόσβασης κινητής συσκευής απενεργοποιήθηκε."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Το σημείο πρόσβασης κινητής συσκευής ενεργοποιήθηκε."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Η μετάδοση της οθόνης διακόπηκε."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Φωτεινότητα οθόνης"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Τα δεδομένα 2G-3G τέθηκαν σε παύση"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Τα δεδομένα 4G τέθηκαν σε παύση"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Χρησιμοποιούνται <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Όριο <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Προειδοποίηση για <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Οι πρόσφατες οθόνες σας εμφανίζονται εδώ"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Πληροφορίες εφαρμογής"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"καρφίτσωμα οθόνης"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Απόρριψη"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> αποτελεί το παράθυρο διαλόγου ελέγχου έντασης"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Αγγίξτε για επαναφορά αρχικού."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Χρησιμοποιείτε το προφίλ εργασίας σας"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Εμφάνιση ποσοστού ενσωματωμένης μπαταρίας"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 84f1785..f3061d7 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -161,6 +161,7 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Ringer silent."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <string name="accessibility_work_mode" msgid="2478631941714607225">"Work mode"</string>
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Dismiss <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> dismissed."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"All recent applications dismissed."</string>
@@ -212,6 +213,10 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobile hotspot turned off."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobile hotspot turned on."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Screen casting stopped."</string>
+    <string name="accessibility_quick_settings_work_mode_off" msgid="7045417396436552890">"Work mode off."</string>
+    <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Work mode on."</string>
+    <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Work mode turned off."</string>
+    <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Work mode turned on."</string>
     <string name="accessibility_brightness" msgid="8003681285547803095">"Display brightness"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G data is paused"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G data is paused"</string>
@@ -289,6 +294,7 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> used"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> limit"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> warning"</string>
+    <string name="quick_settings_work_mode_label" msgid="6244915274350490429">"Work mode"</string>
     <string name="recents_empty_message" msgid="8682129509540827999">"Your recent screens appear here"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Application Info"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"screen pinning"</string>
@@ -403,7 +409,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Deny"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is the volume dialogue"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Touch to restore the original."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <string name="group_summary_concadenation" msgid="6846402378100148789">", "</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"You\'re using your work profile"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Show embedded battery percentage"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 84f1785..f3061d7 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -161,6 +161,7 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Ringer silent."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <string name="accessibility_work_mode" msgid="2478631941714607225">"Work mode"</string>
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Dismiss <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> dismissed."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"All recent applications dismissed."</string>
@@ -212,6 +213,10 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobile hotspot turned off."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobile hotspot turned on."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Screen casting stopped."</string>
+    <string name="accessibility_quick_settings_work_mode_off" msgid="7045417396436552890">"Work mode off."</string>
+    <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Work mode on."</string>
+    <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Work mode turned off."</string>
+    <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Work mode turned on."</string>
     <string name="accessibility_brightness" msgid="8003681285547803095">"Display brightness"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G data is paused"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G data is paused"</string>
@@ -289,6 +294,7 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> used"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> limit"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> warning"</string>
+    <string name="quick_settings_work_mode_label" msgid="6244915274350490429">"Work mode"</string>
     <string name="recents_empty_message" msgid="8682129509540827999">"Your recent screens appear here"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Application Info"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"screen pinning"</string>
@@ -403,7 +409,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Deny"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is the volume dialogue"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Touch to restore the original."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <string name="group_summary_concadenation" msgid="6846402378100148789">", "</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"You\'re using your work profile"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Show embedded battery percentage"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 84f1785..f3061d7 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -161,6 +161,7 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Ringer silent."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <string name="accessibility_work_mode" msgid="2478631941714607225">"Work mode"</string>
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Dismiss <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> dismissed."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"All recent applications dismissed."</string>
@@ -212,6 +213,10 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobile hotspot turned off."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobile hotspot turned on."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Screen casting stopped."</string>
+    <string name="accessibility_quick_settings_work_mode_off" msgid="7045417396436552890">"Work mode off."</string>
+    <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Work mode on."</string>
+    <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Work mode turned off."</string>
+    <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Work mode turned on."</string>
     <string name="accessibility_brightness" msgid="8003681285547803095">"Display brightness"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G data is paused"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G data is paused"</string>
@@ -289,6 +294,7 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> used"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> limit"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> warning"</string>
+    <string name="quick_settings_work_mode_label" msgid="6244915274350490429">"Work mode"</string>
     <string name="recents_empty_message" msgid="8682129509540827999">"Your recent screens appear here"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Application Info"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"screen pinning"</string>
@@ -403,7 +409,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Deny"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is the volume dialogue"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Touch to restore the original."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <string name="group_summary_concadenation" msgid="6846402378100148789">", "</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"You\'re using your work profile"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Show embedded battery percentage"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index c9af193..0d9f55e 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Timbre en silencio"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Rechazar <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> descartada."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Se descartaron todas las aplicaciones recientes."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Zona móvil desactivada"</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Zona móvil activada"</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Transmisión de pantalla detenida"</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Brillo de pantalla"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Datos 2G-3G pausados"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Datos 4G pausados"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Utilizados: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Límite de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Advertencia de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Las pantallas recientes aparecen aquí."</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Información de la aplicación"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"Fijar pantalla"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Rechazar"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> es el cuadro de diálogo de volumen."</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Toca para restaurar el original."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Estás usando tu perfil de trabajo"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Sintonizador de IU del sistema"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar porcentaje de la batería integrada"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 51984bf..a5a39ce 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Modo silencio"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Ignorar <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Se ha eliminado <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Se han ignorado todas las aplicaciones recientes."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Punto de acceso móvil desactivado."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Punto de acceso móvil activado."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Envío de pantalla detenido."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Brillo de la pantalla"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Datos 2G-3G pausados"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Datos 4G pausados"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> utilizado"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Límite de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Advertencia de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Aquí aparecerán tus pantallas recientes"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Información de la aplicación"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fijación de pantalla"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Rechazar"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> es el cuadro de diálogo de volumen"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Toca para restaurar la versión original."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">"y"</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Estás usando tu perfil de trabajo"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Configurador de IU del sistema"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar porcentaje de batería insertado"</string>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index b527b9f..79ab1ee 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Vaikne kõlisti."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Rakendusest <xliff:g id="APP">%s</xliff:g> loobumine."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Loobusite rakendusest <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Kõikidest hiljutistest rakendustest on loobutud"</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobiilside leviala on välja lülitatud."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobiilside leviala on sisse lülitatud."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Ekraanikuva ülekandmine on peatatud."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Ekraani heledus"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G andmekasutus on peatatud"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G andmekasutus on peatatud"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> on kasutatud"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Limiit: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> hoiatus"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Teie viimane ekraanikuva ilmub siia"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Rakenduste teave"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ekraanikuva kinnitamine"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Keela"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> on helitugevuse dialoog"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Originaali taastamiseks puudutage."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Kasutate oma tööprofiili"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Süsteemi kasutajaliidese tuuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Kuva lisatud akutaseme protsent"</string>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index b7cfb2a2..94ce0ff 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Tonu-jotzailea isilik."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Baztertu <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> baztertu da."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Azken aplikazio guztiak baztertu da."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Konexioa partekatzeko aukera desaktibatu egin da."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Konexioa partekatzeko aukera aktibatu egin da."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Pantaila igortzeari utzi zaio."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Bistaratu distira"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G datuen erabilera eten da"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G datuen erabilera eten da"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> erabilita"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Muga: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Abisua: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Ikusitako azken pantailak erakusten dira hemen"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Aplikazioaren informazioa"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"pantaila-ainguratzea"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Ukatu"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> da bolumenaren leihoa"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Ukitu jatorrizkora leheneratzeko"</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Work profila erabiltzen ari zara"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Sistemako erabiltzaile-interfazearen konfiguratzailea"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Erakutsi txertatutako bateriaren ehunekoa"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index b3d8216..9fbafc2 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"زنگ بی‌صدا."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"رد کردن <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> نادیده گرفته شد."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"همه برنامه‌های اخیر رد شدند."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"نقطه اتصال دستگاه همراه خاموش شد."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"نقطه اتصال دستگاه همراه روشن شد."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"فرستادن صفحه نمایش متوقف شد."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"روشنایی نمایشگر"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"‏داده 2G-3G موقتاً متوقف شده است"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"‏داده 4G موقتاً متوقف شده است"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> استفاده شده"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> محدودیت"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"هشدار <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"صفحه‌های اخیر شما اینجا نمایان می‌شوند"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"اطلاعات برنامه"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"پین کردن صفحه"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"اجازه ندارد"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> کنترل‌کننده صدا است"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"برای بازیابی کنترل‌کننده اصلی، لمس کنید."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">"،"</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"درحال استفاده از نمایه کاری‌تان هستید"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"تنظیم‌کننده واسط کاربری سیستم"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"نمایش درصد شارژ باتری جاسازی شده"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 235eef0..6c9e9d6 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Soittoääni: äänetön."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Hylätään <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> hylättiin."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Kaikki viimeisimmät sovellukset on hylätty."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobiiliyhteyden hotspot poistettiin käytöstä."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobiiliyhteyden hotspot otettiin käyttöön."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Ruudun lähetys pysäytettiin."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Näytön kirkkaus"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G-tiedonsiirto keskeytettiin"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G-tiedonsiirto keskeytettiin"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"käytetty <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"kiintiö <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> – varoitus"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Äskettäin käytetyt ruudut näkyvät tässä"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Sovellustiedot"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"näytön kiinnitys"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Estä"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> on äänenvoimakkuusvalinta."</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Palauta alkuperäinen koskettamalla."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Käytät työprofiilia."</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Näytä akun varaus kuvakkeessa"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 3493067..86b207e 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Sonnerie en mode silencieux"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Supprimer <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Application \"<xliff:g id="APP">%s</xliff:g>\" ignorée."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Toutes les applications récentes ont été supprimées."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Point d\'accès mobile désactivé."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Point d\'accès mobile activé."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Diffusion d\'écran arrêtée."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Luminosité de l\'écran"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Données 2G/3G désactivées"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Données 4G désactivées"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Quantité de données utilisées :<xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Limite : <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Avertissement : <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Vos écrans récents s\'affichent ici"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Détails de l\'application"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"épinglage d\'écran"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Refuser"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> correspond à la boîte de dialogue du volume"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Touchez pour restaurer l\'original."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Vous utilisez votre profil professionnel."</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Afficher le pourcentage intégré de charge"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index ebed6e9..6953c87 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Sonnerie en mode silencieux"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Supprimer <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Application \"<xliff:g id="APP">%s</xliff:g>\" ignorée."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Toutes les applications récentes ont été supprimées."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Point d\'accès mobile désactivé."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Point d\'accès mobile activé."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Diffusion d\'écran interrompue."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Luminosité de l\'affichage"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Données 2G-3G désactivées"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Données 4G désactivées"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> utilisés"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> au maximum"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Avertissement : <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Vos écrans récents s\'affichent ici"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Infos application"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"épinglage d\'écran"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Refuser"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> correspond à la boîte de dialogue du volume"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Appuyez pour restaurer l\'interface d\'origine."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Vous utilisez votre profil professionnel."</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Afficher le pourcentage intégré de la batterie"</string>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index a9648b9..2a2a2e0 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Timbre silenciado"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Rexeitar <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Rexeitouse <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Rexeitáronse todas as aplicacións recentes."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Desactivouse a zona interactiva móbil."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Activouse a zona interactiva móbil."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Detívose a emisión en pantalla."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Brillo de pantalla"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Os datos 2G-3G están en pausa"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Os datos 4G están en pausa"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> usados"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Límite de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Advertencia <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"As túas pantallas recentes aparecen aquí"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Información da aplicación"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fixación de pantalla"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Denegar"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> é o cadro de diálogo de volume"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Toca para restaurar o orixinal."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Estás usando o perfil de traballo"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Configurador da IU do sistema"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar porcentaxe de batería inserida"</string>
diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml
index 804a940..6b67a20 100644
--- a/packages/SystemUI/res/values-gu-rIN/strings.xml
+++ b/packages/SystemUI/res/values-gu-rIN/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"રિંગર શાંત છે."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> કાઢી નાખો."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> કાઢી નાખી."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"તમામ તાજેતરની એપ્લિકેશનો કાઢી નાખી."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"મોબાઇલ હોટસ્પોટ બંધ કર્યું."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"મોબાઇલ હોટસ્પોટ ચાલુ કર્યું."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"સ્ક્રીન કાસ્ટિંગ બંધ કર્યું."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"પ્રદર્શન તેજ"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G ડેટા થોભાવ્યો છે"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G ડેટા થોભાવ્યો છે"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> વાપર્યો"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> મર્યાદા"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> ચેતવણી"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"તમારી તાજેતરની સ્ક્રીન્સ અહીં દેખાય છે"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"એપ્લિકેશન માહિતી"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"સ્ક્રીન પિનિંગ"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"નકારો"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> એ વૉલ્યૂમ સંવાદ છે"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"મૂળને પુનઃસ્થાપિત કરવા માટે ટચ કરો."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"તમે તમારી કાર્ય પ્રોફાઇલનો ઉપયોગ કરી રહ્યાં છો"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"સિસ્ટમ UI ટ્યૂનર"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"એમ્બેડ કરેલ બૅટરી ટકા બતાવો"</string>
diff --git a/packages/SystemUI/res/values-h560dp/config.xml b/packages/SystemUI/res/values-h560dp/config.xml
index f210d7b..8b576b9 100644
--- a/packages/SystemUI/res/values-h560dp/config.xml
+++ b/packages/SystemUI/res/values-h560dp/config.xml
@@ -18,6 +18,6 @@
 
 <resources>
     <!-- The maximum number of items to be displayed in quick settings -->
-    <integer name="quick_settings_detail_max_item_count">8</integer>
+    <integer name="quick_settings_detail_max_item_count">6</integer>
 </resources>
 
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 354de04..feba1fe 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"रिंगर मौन."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> को ख़ारिज करें."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> खा़रिज कर दिया गया."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"हाल ही के सभी ऐप्लिकेशन ख़ारिज कर दिए गए."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"मोबाइल हॉटस्‍पॉट को बंद किया गया."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"मोबाइल हॉटस्‍पॉट को चालू किया गया."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"स्‍क्रीन कास्‍ट करना रुक गया."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"स्क्रीन की स्क्रीन की रोशनी"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G डेटा रोक दिया गया है"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G डेटा रोक दिया गया है"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> उपयोग किया गया"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> सीमा"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> चेतावनी"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"आपकी हाल की स्‍क्रीन यहां दिखाई देती हैं"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"एप्‍लिकेशन जानकारी"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"स्क्रीन पिन करना"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"अस्वीकार करें"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> वॉल्यूम संवाद है"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"मूल वॉल्यूम को फिर से लाने के लिए स्पर्श करें."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"आप अपनी कार्य प्रोफ़ाइल का उपयोग कर रहे हैं"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"सिस्टम UI ट्यूनर"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"एम्बेड किया गया बैटरी प्रतिशत दिखाएं"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index b35360e..de1ca72 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -162,6 +162,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Softver zvona utišan."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Odbacivanje aplikacije <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Aplikacija <xliff:g id="APP">%s</xliff:g> odbačena je."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Odbačene su sve nedavne aplikacije."</string>
@@ -213,6 +215,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobilna žarišna točka isključena."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobilna žarišna točka uključena."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Emitiranje zaslona zaustavljeno."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Svjetlina zaslona"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G – 3G podaci pauzirani"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G podaci pauzirani"</string>
@@ -290,6 +300,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> iskorišteno"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Ograničenje od <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Upozorenje <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Ovdje se pojavljuju vaši nedavni zasloni"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informacije o aplikaciji"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"prikvačivanje zaslona"</string>
@@ -404,7 +416,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Odbij"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> predstavlja dijaloški okvir za upravljanje glasnoćom"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Dodirnite da biste vratili izvorno."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Upotrebljavate radni profil"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Ugađanje korisničkog sučelja sustava"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Prikaži ugrađeni postotak baterije"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 7956a21..7763fa7 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Csengő néma."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"A(z) <xliff:g id="APP">%s</xliff:g> elvetése."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> eltávolítva."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Az összes alkalmazás eltávolítva a nemrég használtak közül."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"A mobil hotspot kikapcsolva."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"A mobil hotspot bekapcsolva."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"A képernyő átküldése leállítva."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"A kijelző fényereje"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"A 2G és 3G adatforgalom szünetel."</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"A 4G adatforgalom szünetel"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> felhasználva"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> korlát"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Figyelem! <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"A legutóbbi képernyők itt jelennek meg"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Az alkalmazás adatai"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"képernyő rögzítése"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Elutasítás"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás kezeli a hangerőt"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Érintse meg az eredeti érték visszaállításához."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"A munkaprofilt használja"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Kezelőfelület-hangoló"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"A beépített akkumulátor töltöttségi szintjének megjelenítése"</string>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index de70fec..cbb9a89 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Զանգակը լռեցված է:"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Անտեսել <xliff:g id="APP">%s</xliff:g>-ը:"</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g>-ը անտեսված է:"</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Բոլոր վերջին հավելվածները հեռացվել են ցուցակից:"</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Շարժական կապի WiFi ցրիչն անջատվեց:"</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Շարժական կապի WiFi ցրիչը միացավ:"</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Էկրանի հեռարձակումն ընդհատվեց:"</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Ցուցադրել պայծառությունը"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2Գ-3Գ տվյալների օգտագործումը դադարեցված է"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4Գ տվյալների օգտագործումը դադարեցված է"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Օգտագործված է՝ <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Սահմանաչափ՝ <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> զգուշացում"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Ձեր վերջին էկրանները տեսանելի են այստեղ"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Հավելվածի մասին"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"էկրանի ամրակցում"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Մերժել"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ը ձայնի ուժգնության երկխոսության հավելված է"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Դիպչեք՝ սկզբնօրինակը վերականգնելու համար:"</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Դուք օգտագործում եք ձեր աշխատանքային պրոֆիլը"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Համակարգի ՕՄ-ի կարգավորիչ"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Ցուցադրել ներկառուցված մարտկոցի տոկոսայնությունը"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 51ddcc0..bbf018d 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Pendering senyap."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Menyingkirkan <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> disingkirkan."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Semua aplikasi terbaru telah ditutup."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Hotspot seluler dinonaktifkan."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Hotspot seluler diaktifkan."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Transmisi layar berhenti."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Kecerahan tampilan"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Data 2G-3G dijeda"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Data 4G dijeda"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> digunakan"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Batas <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Peringatan <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Layar terkini Anda muncul di sini"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Info Aplikasi"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"pin ke layar"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Tolak"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> adalah dialog volume"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Sentuh untuk memulihkan aslinya."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Anda menggunakan profil kerja"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Penyetel Antarmuka Pengguna Sistem"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Tampilkan persentase baterai yang tersemat"</string>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index 20d8693..f9235a0 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Engin hringing."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Hunsa <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> vísað frá."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Öll nýleg forrit fjarlægð."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Slökkt á farsímaaðgangsstað."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Kveikt á farsímaaðgangsstað."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Skjáútsendingu hætt."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Birtustig skjás"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Slökkt er á 2G- og 3G-gögnum"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Slökkt er á 4G-gögnum"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> notuð"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> hámark"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> viðvörun"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Nýlegar skjámyndir birtast hér"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Forritsupplýsingar"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"skjáfesting"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Hafna"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> er hljóðstyrksvalmyndin"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Snertu til að færa í upprunalegt horf."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Þú ert að nota vinnusniðið"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Fínstillingar kerfisviðmóts"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Sýna innfellda rafhlöðustöðu"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 87267995..a389126 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Suoneria silenziosa."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Elimina <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> eliminata."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Tutte le applicazioni recenti sono state rimosse."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Hotspot mobile disattivato."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Hotspot mobile attivato."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Trasmissione dello schermo interrotta."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Luminosità dello schermo"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Dati 2G-3G sospesi"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Dati 4G sospesi"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> utilizzati"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Limite di <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Avviso <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Le tue schermate recenti vengono visualizzate in questa sezione"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informazioni sull\'applicazione"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"blocco su schermo"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Nega"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> rappresenta la finestra di dialogo relativa al volume"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Tocca per ripristinare l\'originale."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Stai utilizzando il profilo di lavoro"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Sintetizzatore interfaccia utente di sistema"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Mostra percentuale batteria incorporata"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index a28dc2a..cd64034 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -163,6 +163,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"צלצול שקט."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"סגור את <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> נדחה."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"כל האפליקציות האחרונות נסגרו."</string>
@@ -214,6 +216,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"נקודה לשיתוף אינטרנט בנייד כבויה."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"נקודה לשיתוף אינטרנט בנייד מופעלת."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"העברת המסך הופסקה."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"בהירות תצוגה"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"‏השימוש בנתוני 2G-3G מושהה"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"‏השימוש בנתוני 4G מושהה"</string>
@@ -291,6 +301,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> בשימוש"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"הגבלה של <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"אזהרה - <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"המסכים האחרונים מופיעים כאן"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"מידע על האפליקציה"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"הצמדת מסך"</string>
@@ -405,7 +417,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"דחה"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> הוא תיבת הדו-שיח של עוצמת הקול"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"גע כדי לשחזר את עוצמת הקול המקורית."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"אתה משתמש בפרופיל העבודה שלך"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"הצג בשורת הסטטוס את אחוז עוצמת הסוללה"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 13217a0..39c7161 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"マナーモード着信。"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>を削除します。"</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g>は削除されました。"</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"最近のアプリケーションをすべて消去しました。"</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"モバイルアクセスポイントをOFFにしました。"</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"モバイルアクセスポイントをONにしました。"</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"画面のキャストが停止しました。"</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"ディスプレイの明るさ"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G~3Gデータは一時停止中です"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4Gデータは一時停止中です"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g>使用中"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"上限: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"警告: 上限は<xliff:g id="DATA_LIMIT">%s</xliff:g>です"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"ここに最近の画面が表示されます"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"アプリ情報"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"画面固定"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"許可しない"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>を音量ダイアログとして使用"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"タップすると元の音量ダイアログが復元されます。"</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">"、"</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"仕事用プロファイルを使用しています"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"システムUI調整ツール"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"内蔵電池の残量の割合を表示する"</string>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index c4e84a8..234891f 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"უხმო რეჟიმი."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>-ის უგულებელყოფა."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ამოშლილია სიიდან."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"ყველა ბოლო აპლიკაცია გაუქმდა."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"მობილური ქსელის წერტილი გამოირთო."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"მობილური ქსელის წერტილი ჩაირთო."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"ეკრანის გადაცემა შეჩერებულია."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"ეკრანის სიკაშკაშე"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G მონაცემები შეჩერებულია"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G მონაცემები შეჩერებულია"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"გამოყენებულია: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"ლიმიტი: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> გაფრთხილება"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"თქვენი ბოლო ეკრანები აქ გამოჩნდება"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"აპლიკაციის შესახებ"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ეკრანზე ჩამაგრება"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"უარყოფა"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ხმოვან დიალოგშია"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"ორიგინალის აღდგენისათვის, შეეხეთ."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"თქვენ სამსახურის პროფილს იყენებთ"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"სისტემის UI ტუნერი"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"ჩამაგრებული ბატარეის პროცენტის ჩვენება"</string>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index 2133170..08e2a50 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Қоңырау үнсіз."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> қолданбасынан бас тарту."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> алынып тасталған."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Барлық жақындағы қабылданбаған қолданбалар."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Мобильді хотспот өшірілді."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Мобильді хотспот қосылды."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Экранды трансляциялау тоқтатылды."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Дисплей жарықтығы"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G деректері кідіртілді"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G деректері кідіртілді"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> пайдаланылған"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> шегі"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> туралы ескерту"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Мұнда жақындағы экрандар көрсетіледі"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Қолданба туралы ақпарат"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"экранды бекіту"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Өшіру"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> — көлем диалогтық терезесі"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Түпнұсқаны қалпына келтіру үшін түртіңіз."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Сіз жұмыс профиліңізді пайдаланып жатырсыз"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Жүйелік пайдаланушылық интерфейс тюнері"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Ендірілген батарея пайыздық шамасын көрсету"</string>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 6fbb325..2df7f1f 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"កម្មវិធី​រោទ៍​ស្ងាត់។"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"បោះបង់ <xliff:g id="APP">%s</xliff:g> ។"</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> បដិសេធ។"</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"កម្មវិធីថ្មីៗទាំងអស់ត្រូវបានបោះបង់។"</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"បាន​បិទ​ហតស្ប៉ត​ចល័ត។"</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"បាន​បើក​ហតស្ប៉ត​ចល័ត។"</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"បាន​បញ្ឈប់​ការ​ចាត់​ថ្នាក់​អេក្រង់។"</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"ពន្លឺ​ការ​បង្ហាញ"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"ទិន្នន័យ 2G-3G ត្រូវបានផ្អាក"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"ទិន្នន័យ 4G ត្រូវបានផ្អាក"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"បាន​ប្រើ <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"ដែន​កំណត់ <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> ការ​ព្រមាន"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"អេក្រង់​បច្ចុប្បន្ន​របស់​អ្នក​បង្ហាញ​នៅ​ទីនេះ"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"ព័ត៌មាន​កម្មវិធី"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ការ​ភ្ជាប់​អេក្រង់"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"បដិសេធ"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> គឺជាប្រអប់សម្លេង"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"ប៉ះដើម្បីស្តារច្បាប់ដើម។"</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"អ្នកកំពុងប្រើប្រវត្តិរូបការងាររបស់អ្នក"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"កម្មវិធីសម្រួល UI ប្រព័ន្ធ"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"បង្ហាញភាគរយថាមពលថ្មដែលបានបង្កប់"</string>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index c8fc91d..ee466d0 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"ರಿಂಗರ್ ಶಾಂತ."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> ವಜಾಗೊಳಿಸು."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ವಜಾಗೊಳಿಸಲಾಗಿದೆ."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"ಇತ್ತೀಚಿನ ಎಲ್ಲಾ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ವಜಾಗೊಳಿಸಲಾಗಿದೆ."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"ಮೊಬೈಲ್ ಹಾಟ್‌ಸ್ಪಾಟ್ ಆಫ್ ಮಾಡಲಾಗಿದೆ."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"ಮೊಬೈಲ್ ಹಾಟ್‌ಸ್ಪಾಟ್ ಆನ್ ಮಾಡಲಾಗಿದೆ."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"ಸ್ಕ್ರೀನ್ ಪ್ರಸಾರವನ್ನು ನಿಲ್ಲಿಸಲಾಗಿದೆ."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"ಹೊಳಪನ್ನು ಪ್ರದರ್ಶಿಸಿ"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G ಡೇಟಾವನ್ನು ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G ಡೇಟಾ ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> ಬಳಸಲಾಗಿದೆ"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> ಮಿತಿ"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> ಎಚ್ಚರಿಕೆ"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"ನಿಮ್ಮ ಇತ್ತೀಚಿನ ಪರದೆಗಳು ಇಲ್ಲಿ ಕಾಣಿಸಿಕೊಳ್ಳುತ್ತವೆ"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿ"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ಸ್ಕ್ರೀನ್ ಪಿನ್ನಿಂಗ್"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"ನಿರಾಕರಿಸು"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ವಾಲ್ಯೂಮ್ ಸಂವಾದವಾಗಿದೆ"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"ಮೂಲ ಮರುಸ್ಥಾಪಿಸಲು ಸ್ಪರ್ಶಿಸಿ."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ನಿಮ್ಮ ಕೆಲಸದ ಪ್ರೊಫೈಲ್‌ ಅನ್ನು ನೀವು ಬಳಸುತ್ತಿರುವಿರಿ"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"ಸಿಸ್ಟಮ್ UI ಟ್ಯೂನರ್"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"ಎಂಬೆಡ್ ಮಾಡಲಾದ ಬ್ಯಾಟರಿ ಶೇಕಡಾ ತೋರಿಸಿ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 1296d21..35725aa 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"벨소리가 무음입니다."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>을(를) 숨깁니다."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g>이(가) 제거되었습니다."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"최근 사용한 애플리케이션을 모두 닫았습니다."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"모바일 핫스팟이 사용 중지되었습니다."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"모바일 핫스팟을 사용합니다."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"화면 전송이 중지되었습니다."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"디스플레이 밝기"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G 데이터 사용 중지됨"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G 데이터 사용 중지됨"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> 사용됨"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"한도: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> 경고"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"여기에 최근 화면이 표시됩니다."</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"애플리케이션 정보"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"화면 고정"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"거부"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>은(는) 볼륨 대화입니다."</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"원본을 복원하려면 터치하세요."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"직장 프로필을 사용하고 있습니다."</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"시스템 UI 튜너"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"내장형 배터리 잔량 비율 표시"</string>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index ead55c7..79b8937 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Үнсүз шыңгыроо."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> этибарга албоо."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> жок болду."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Акыркы колдонмолордун баары көз жаздымда калтырылды."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Мобилдик байланыш түйүнү өчүрүлдү."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Мобилдик байланыш түйүнү күйгүзүлдү."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Тышкы экранга чыгаруу аракети токтотулду."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Жарыктыгын көрсөтүү"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G дайындары тындырылды."</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G дайындары тындырылды"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> колдонулду"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> чектөө"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> эскертүү"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Акыркы экрандарыңыз бул жерден көрүнөт"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Колдонмо жөнүндө маалымат"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"экран кадоо"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Жок"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> үндү катуулатуу диалогу"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Түпнусканы калыбына келтирүү үчүн тийип коюңуз."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Жумуш профилиңизди колдонуп жатасыз"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Батарянын кубатнын деңгээли пайыз менен көрсөтлсүн"</string>
diff --git a/packages/SystemUI/res/values-land/styles.xml b/packages/SystemUI/res/values-land/styles.xml
index dd396d9..96d8fb8 100644
--- a/packages/SystemUI/res/values-land/styles.xml
+++ b/packages/SystemUI/res/values-land/styles.xml
@@ -27,6 +27,8 @@
 
     <style name="DockedDividerHandle">
         <item name="android:layout_gravity">center_vertical</item>
+        <item name="android:layout_width">48dp</item>
+        <item name="android:layout_height">64dp</item>
     </style>
 
 </resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index c0689c3..015d4da 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"ປິດສຽງ."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"ປິດ <xliff:g id="APP">%s</xliff:g> ໄວ້."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"ປິດ <xliff:g id="APP">%s</xliff:g> ແລ້ວ."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"ທຸກ​ແອັບ​ພ​ລິ​ເຄ​ຊັນ​ບໍ່​ດົນ​ມາ​ນີ້​ຖືກ​ປ່ອຍ​ໄປ."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"ປິດ​ຮັອດ​ສະ​ປອດ​ເຄື່ອນ​ທີ່​ແລ້ວ."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"ເປີດ​ຮັອດ​ສະ​ປອດ​ເຄື່ອນ​ທີ່​ແລ້ວ."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"ຢຸດ​ການ​ສົ່ງ​​ພາບ​ໜ້າ​ຈໍ​ແລ້ວ."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"​ຄວາມ​ແຈ້ງ​​ຂອງ​ຈໍ"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"ຂໍ້​ມູນ 2G​-3G ຢຸດ​ຊົ່ວ​ຄາວແລ້ວ"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"ຂໍ້​ມູນ 4G ຢຸດ​ຊົ່ວ​ຄາວແລ້ວ"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"ໃຊ້​ໄປ​ແລ້ວ <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"ຈຳ​ກັດ <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"ຄຳ​ເຕືອນ <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Your recent screens appear here"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"​ຂໍ້​ມູນ​ແອັບ​ພ​ລິ​ເຄ​ຊັນ"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ການ​ປັກ​ໝຸດ​ໜ້າ​ຈໍ​"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"ປະຕິເສດ"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ແມ່ນ​ໜ້າ​ຕ່າງ​ລະ​ດັບ​ສຽງ"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"ສໍາ​ຜັດ​ເພື່ອກູ້​ຄືນ​ຕົ້ນ​ສະ​ບັບ​."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ທ່ານກຳລັງໃຊ້ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຂອງທ່ານ"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"ສະ​ແດງ​ເປີ​ເຊັນ​ແບັດ​ເຕີ​ຣີ​ທີ່​ຕິດ​ມາ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 4425d31..282866f 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -163,6 +163,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Skambutis tylus."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Atsisakyti <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Atsisakyta programos „<xliff:g id="APP">%s</xliff:g>“."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Atsisakyta visų naujausių programų."</string>
@@ -214,6 +216,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobiliojo ryšio viešosios interneto prieigos taškas išjungtas."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobiliojo ryšio viešosios interneto prieigos taškas įjungtas."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Ekrano perdavimas sustabdytas."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Ekrano šviesumas"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G duomenys pristabdyti"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G duomenys pristabdyti"</string>
@@ -291,6 +301,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Išnaudota: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Limitas: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> įspėjimas"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Čia rodomi naujausi ekranai"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Programos informacija"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ekrano prisegimas"</string>
@@ -405,7 +417,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Atmesti"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ yra garsumo valdymo dialogo langas"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Palieskite, kad atkurtumėte originalą."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Naudojate darbo profilį"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Sistemos naudotojo sąsajos derinimo priemonė"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Rodyti įterptą akumuliat. įkrovos procentinę vertę"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index eca57a6..8e99c57 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -162,6 +162,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Zvana signāls — kluss."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Nerādīt lietotni <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Lietotne <xliff:g id="APP">%s</xliff:g> vairs netiek rādīta."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Visas nesen izmantotās lietojumprogrammas tika noņemtas."</string>
@@ -213,6 +215,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobilais tīklājs ir izslēgts."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobilais tīklājs ir ieslēgts."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Ekrāna apraidīšana ir apturēta."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Ekrāna spilgtums"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G datu lietojums ir apturēts"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G datu lietojums ir apturēts"</string>
@@ -290,6 +300,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Tiek izmantots: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Ierobežojums: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> brīdinājums"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Jūsu pēdējie ekrāni tiek rādīti šeit."</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informācija par lietojumprogrammu"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"Piespraust ekrānu"</string>
@@ -404,7 +416,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Neatļaut"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ir skaļuma dialoglodziņš"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Pieskarieties, lai atjaunotu sākotnējo."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Jūs izmantojat darba profilu."</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Sistēmas saskarnes regulators"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Rādīt akumulatora uzlādes līmeni procentos"</string>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml
index 038c669..c2de755 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Ѕвонче на тивко."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Отфрли <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> е отфрлена."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Сите неодамнешни апликации се отфрлени."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Мобилната точка на пристап е исклучена."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Мобилната точка на пристап е вклучена."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Емитувањето на екранот запре."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Осветленост на екранот"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Податоците 2G-3G се паузирани"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Податоците 4G се паузирани"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Искористено: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Лимит: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Предупредување за <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Вашите неодамнешни екрани се појавуваат тука"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Информации за апликацијата"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"прикачување екран"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Одбиј"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> е дијалог за јачина на звук"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Допрете за да го вратите оригиналот."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Го користите работниот профил"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Адаптер на УИ на системот"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Прикажи вграден процент на батеријата"</string>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml
index f4964d0..5594792 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"റിംഗർ നിശ്ശബ്‌ദമാണ്."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> നിരസിക്കുക."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> നിരസിച്ചു."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"അടുത്തിടെയുള്ള എല്ലാ അപ്ലിക്കേഷനും നിരസിച്ചു."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"മൊബൈൽ ഹോട്ട്‌സ്‌പോട്ട് ഓഫാക്കി."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"മൊബൈൽ ഹോട്ട്‌സ്‌പോട്ട് ഓണാക്കി."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"സ്ക്രീൻ കാസ്‌റ്റുചെയ്യൽ നിർത്തി."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"ഡിസ്പ്ലേ തെളിച്ചം"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G ഡാറ്റ താൽക്കാലികമായി നിർത്തി"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G ഡാറ്റ താൽക്കാലികമായി നിർത്തി"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> ഉപയോഗിച്ചു"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> പരിധി"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> മുന്നറിയിപ്പ്"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"നിങ്ങളുടെ പുതിയ സ്ക്രീനുകൾ ഇവിടെ ദൃശ്യമാകുന്നു"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"ആപ്പ് വിവരം"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"സ്ക്രീൻ പിൻ ചെയ്യൽ"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"നിരസിക്കുക"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>, വോളിയം ഡയലോഗാണ്"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"ആദ്യത്തേത് പുനഃസ്ഥാപിക്കാൻ സ്‌പർശിക്കുക."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"നിങ്ങൾ ഉപയോഗിക്കുന്നത് ഔദ്യോഗിക പ്രൊഫൈലാണ്"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"സിസ്റ്റം UI ട്യൂണർ"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"എംബഡ് ചെയ്‌ത ബാറ്ററി ശതമാനം കാണിക്കുക"</string>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index 122068c..260a580 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -159,6 +159,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Хонхыг хаах."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>-г хаах."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> байхгүй."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Хамгийн сүүлийн бүх програмыг арилгасан байна."</string>
@@ -210,6 +212,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Мобайл хотспотыг унтраасан."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Мобайл хотспотыг асаасан."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Дэлгэц дамжуулалт зогссон."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Дэлгэцийн гэрэлтэлт"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G дата-г түр зогсоосон байна"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G дата-г түр зогсоосон байна"</string>
@@ -287,6 +297,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> ашигласан"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> хязгаар"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> анхааруулга"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Таны саяхны дэлгэц энд харагдах болно"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Аппликешны мэдээлэл"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"дэлгэц тогтоох"</string>
@@ -401,7 +413,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Татгалзах"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь дууны диалог юм."</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Анхны хувилбарыг эргүүлэн хадгалахыг хүсвэл хүрнэ үү."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Та өөрийн ажлын профайлыг ашиглаж байна"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Системийн UI Тохируулагч"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Залгаатай тэжээлийн хувийг харуулах"</string>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index 6415adb..0c7f795 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"रिंगर मूक."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> डिसमिस करा."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> डिसमिस केला."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"अलीकडील सर्व अनुप्रयोग डिसमिस झाले."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"मोबाईल हॉटस्पॉट बंद केला."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"मोबाईल हॉटस्पॉट चालू केला."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"स्क्रीन कास्ट करणे थांबले."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"प्रदर्शन चमक"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G डेटास विराम दिला आहे"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G डेटास विराम दिला आहे"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> वापरले"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> मर्यादा"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> चेतावणी"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"आपल्या अलीकडील स्क्रीन येथे दिसतात"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"अनुप्रयोग माहिती"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"स्‍क्रीन पिन करणे"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"नकार द्या"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> हा व्हॉल्यूम संवाद आहे"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"मूळ पुनर्संचयित करण्यासाठी स्पर्श करा."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"आपण आपले कार्य प्रोफाईल वापरत आहात"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"सिस्टीम UI ट्यूनर"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"एम्बेडेड बॅटरी टक्केवारी दर्शवा"</string>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index ceefc29..9772a3c 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Pendering senyap."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Ketepikan <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ditolak."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Semua aplikasi terbaharu diketepikan."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Tempat liputan mudah alih bergerak dimatikan."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Tempat liputan mudah alih bergerak dihidupkan."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Penghantaran skrin dihentikan."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Kecerahan paparan"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Data 2G-3G dijeda"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Data 4G dijeda"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> digunakan"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> had"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Amaran <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Skrin terbaru anda terpapar di sini"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Maklumat Aplikasi"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"penyematan skrin"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Tolak"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ialah dialog kelantangan"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Sentuh untuk memulihkan yang asal."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Anda sedang menggunakan profil kerja"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Penala UI Sistem"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Tunjukkan peratusan bateri terbenam"</string>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index 81c0932..2b1acfb 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"ဖုန်းမြည်သံပိတ်သည်။"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>ကို ပယ်လိုက်ရန်"</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ထုတ်ထားသည်။"</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"မကြာသေးမီက အပလီကေးရှင်းများအားလုံး ဖယ်ထုတ်ပြီးပါပြီ။"</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"မိုဘိုင်း ဟော့စပေါ့ ပိတ်ထား။"</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"မိုဘိုင်း ဟော့စပေါ့ ဖွင့်ထား။"</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"မျက်နှာပြင် ကာစ်တင် လုပ်မှု ရပ်လိုက်ပြီ။"</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"တောက်ပမှုကို ပြရန်"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G ဒေတာ ခေတ္တရပ်တန့်သည်"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G data ခေတ္တရပ်တန့်သည်"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> သုံးထား"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> ကန့်သတ်ချက်"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> သတိပေးချက်"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"သင်၏ မကြာမီက မျက်နှာပြင်များ ဒီမှာ ပေါ်လာကြမည်"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"အပလီကေးရှင်း အင်ဖို"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"မျက်နှာပြင် ပင်ထိုးမှု"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"ငြင်းပယ်သည်"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် အသံဒိုင်ယာလော့ခ်ဖြစ်သည်"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"မူရင်းအားပြန်လည်သိမ်းဆည်းရန် ထိပါ။"</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">"၊"</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"သင်သည် အလုပ်ပရိုဖိုင်းအား သုံးနေသည်"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"စနစ် UI ဖမ်းစက်"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"မြုတ်ထားသည့် ဘတ်ထရီ ရာခိုင်နှုန်းကို ပြပါ"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 7f6895e..6dcd6bc 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Stille modus."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Avvis <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> avvist."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Alle nylig brukte apper er avvist."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobil Wi-Fi-sone er slått av."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobil Wi-Fi-sone er slått på."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Skjermcastingen er stoppet."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Lysstyrken på skjermen"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G- og 3G-data er satt på pause"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G-data er satt på pause"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> brukt"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Grense på <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Advarsel for <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"De sist brukte skjermene dine vises her"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Appinformasjon"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"én-appsmodus"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Ikke tillat"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> er volumdialogen"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Trykk for å gå tilbake til den opprinnelige volumdialogen."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Du bruker jobbprofilen din"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Vis prosent for det innebygde batteriet"</string>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index 51e8a16..a05ce9b 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"घन्टी मौन।"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> खारेज गर्नुहोस्।"</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> खारेज गरिएको छ।"</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"सबै हालका अनुप्रयोगहरू खारेज गरियो।"</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"मोबाइल हटस्पट बन्द गरियो।"</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"मोबाइल हटस्पट खुला गरियो।"</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"स्क्रिन कास्टिङ रोकियो।"</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"प्रदर्शन चमक"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G डेटा रोकिएको छ"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G डेटा रोकिएको छ"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> प्रयोग गरियो"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> सीमा"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> चेतावनी दिँदै"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"तपाईँको हालको स्क्रिन यहाँ प्रकट हुन्छ"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"अनुप्रयोग जानकारी"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"स्क्रिन पिन गर्दै"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"अस्वीकार गर्नुहोस्"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> भोल्यूम संवाद हो"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"मूल पुनर्स्थापना गर्न छुनुहोस्।"</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"तपाईँले कार्य प्रोफाइल प्रयोग गर्दै हुनुहुन्छ"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"प्रणाली UI ट्युनर"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"इम्बेड गरिएको ब्याट्री प्रतिशत देखाउनुहोस्"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 88d0b4b..7ded71c 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -161,6 +161,7 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Belsoftware stil."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <string name="accessibility_work_mode" msgid="2478631941714607225">"Werkmodus"</string>
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> sluiten."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> verwijderd."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Alle recente apps gesloten."</string>
@@ -212,6 +213,10 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobiele hotspot uitgeschakeld."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobiele hotspot ingeschakeld."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Casten van scherm gestopt."</string>
+    <string name="accessibility_quick_settings_work_mode_off" msgid="7045417396436552890">"Werkmodus uit."</string>
+    <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Werkmodus aan."</string>
+    <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Werkmodus uitgeschakeld."</string>
+    <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Werkmodus ingeschakeld."</string>
     <string name="accessibility_brightness" msgid="8003681285547803095">"Helderheid van het scherm"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G/3G-data zijn onderbroken"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G-data zijn onderbroken"</string>
@@ -289,6 +294,7 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> gebruikt"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Limiet van <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Waarschuwing voor <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <string name="quick_settings_work_mode_label" msgid="6244915274350490429">"Werkmodus"</string>
     <string name="recents_empty_message" msgid="8682129509540827999">"Je recente schermen worden hier weergegeven"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"App-informatie"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"scherm vastzetten"</string>
@@ -403,7 +409,7 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Afwijzen"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is het volumedialoogvenster"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Tik hierop om het origineel te herstellen."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <string name="group_summary_concadenation" msgid="6846402378100148789">", "</string>
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"U gebruikt je werkprofiel"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Systeem-UI-tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Percentage ingebouwde accu weergeven"</string>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml
index df6c473af..02838bd 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"ਰਿੰਗਰ ਸਾਈਲੈਂਟ।"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> ਨੂੰ ਰੱਦ ਕਰੋ।"</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ਰੱਦ ਕੀਤਾ।"</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"ਸਾਰੀਆਂ ਹਾਲੀਆ ਐਪਲੀਕੇਸ਼ਨਾਂ ਰੱਦ ਕੀਤੀਆਂ।"</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"ਮੋਬਾਈਲ ਹੌਟਸਪੌਟ ਬੰਦ ਕੀਤੀ।"</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"ਮੋਬਾਈਲ ਹੌਟਸਪੌਟ ਚਾਲੂ ਕੀਤੀ।"</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"ਸਕ੍ਰੀਨ ਜੋੜਨਾ ਬੰਦ ਹੋਇਆ।"</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"ਡਿਸਪਲੇ ਚਮਕ"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G ਡਾਟਾ ਰੁਕ ਗਿਆ ਹੈ"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G ਡਾਟਾ ਰੁਕ ਗਿਆ ਹੈ"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> ਵਰਤਿਆ"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> ਸੀਮਾ"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> ਚਿਤਾਵਨੀ"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"ਤੁਹਾਡੀਆਂ ਹਾਲੀਆ ਸਕ੍ਰੀਨਾਂ ਇੱਥੇ ਪ੍ਰਗਟ ਹੋਣਗੀਆਂ"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"ਐਪਲੀਕੇਸ਼ਨ ਜਾਣਕਾਰੀ"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ਸਕ੍ਰੀਨ ਪਿਨਿੰਗ"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਵੋਲਯੂਮ ਡਾਇਲੌਗ ਹੈ"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"ਅਸਲੀ ਨੂੰ ਰੀਸਟੋਰ ਕਰਨ ਲਈ ਛੋਹਵੋ।"</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ਤੁਸੀਂ ਆਪਣੀ ਕੰਮ ਪ੍ਰੋਫਾਈਲ ਵਰਤ ਰਹੇ ਹੋ"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI ਟਿਊਨਰ"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"ਜੋਡ਼ੀ ਗਈ ਬੈਟਰੀ ਪ੍ਰਤਿਸ਼ਤਤਾ ਦਿਖਾਓ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 694132b..d9d1dc4 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -163,6 +163,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Dzwonek wyciszony."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Usuń stąd <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g>: zamknięto."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Wszystkie ostatnie aplikacje zostały zamknięte."</string>
@@ -214,6 +216,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobilny hotspot został wyłączony."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobilny hotspot został włączony."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Zatrzymano przesyłanie ekranu."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Jasność wyświetlacza"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Transmisja danych 2G-3G została wstrzymana"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Transmisja danych 4G została wstrzymana"</string>
@@ -291,6 +301,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Wykorzystano <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Limit <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Ostrzeżenie: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Tutaj pojawią się ostatnie ekrany"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informacje o aplikacji"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"przypinanie ekranu"</string>
@@ -405,7 +417,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Odmów"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> steruje głośnością"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Dotknij, by przywrócić pierwotną."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Używasz profilu do pracy"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Kalibrator System UI"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Pokaż procent naładowania baterii"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index e806bfc..7404621 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Campainha silenciosa."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Descartar <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> descartado."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Todos os apps recentes foram dispensados."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"O ponto de acesso móvel foi desativado."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"O ponto de acesso móvel foi ativado."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"A transmissão de tela foi interrompida."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Brilho da tela"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Os dados 2G e 3G foram pausados"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Os dados 4G foram pausados"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Usados: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Limite: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Aviso de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Suas telas recentes aparecem aqui"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informações do app"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fixação de tela"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Negar"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> é a caixa de diálogo referente ao volume"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Toque para restaurar o original."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Você está usando seu perfil de trabalho"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Sintonizador System UI"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar porcentagem de bateria incorporada"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 468c75d..e14194b 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Campainha em silêncio."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Ignorar <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ignorado."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Todas as aplicações recentes foram ignoradas."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Zona Wi-Fi móvel desligada."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Zona Wi-Fi móvel ligada."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Transmissão do ecrã interrompida."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Brilho do visor"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Dados 2G-3G em pausa"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Dados 4G em pausa"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> utilizado(s)"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Limite de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Aviso de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Os ecrãs recentes aparecem aqui"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informações da aplicação"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fixação no ecrã"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Recusar"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> é a caixa de diálogo do volume"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Toque para restaurar o original."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Está a utilizar o seu perfil de trabalho"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Sintonizador da interface do sistema"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar percentagem da bateria incorporada"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index e806bfc..7404621 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Campainha silenciosa."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Descartar <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> descartado."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Todos os apps recentes foram dispensados."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"O ponto de acesso móvel foi desativado."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"O ponto de acesso móvel foi ativado."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"A transmissão de tela foi interrompida."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Brilho da tela"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Os dados 2G e 3G foram pausados"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Os dados 4G foram pausados"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Usados: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Limite: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Aviso de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Suas telas recentes aparecem aqui"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informações do app"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fixação de tela"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Negar"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> é a caixa de diálogo referente ao volume"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Toque para restaurar o original."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Você está usando seu perfil de trabalho"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Sintonizador System UI"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar porcentagem de bateria incorporada"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 1b8e8de..eacc909 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -162,6 +162,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Sonerie silențioasă."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Închideți <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> a fost eliminată."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Toate aplicațiile recente au fost închise."</string>
@@ -213,6 +215,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Hotspotul mobil este dezactivat."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Hotspotul mobil este activat."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Transmiterea ecranului a fost oprită."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Luminozitatea ecranului"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Conexiunea de date 2G – 3G este întreruptă"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Conexiunea de date 4G este întreruptă"</string>
@@ -290,6 +300,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> utilizați"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Limită de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Avertizare: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Ecranele dvs. recente apar aici"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informații despre aplicație"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fixare pe ecran"</string>
@@ -404,7 +416,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Refuzați"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> afișează caseta de dialog pentru volum"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Atingeți pentru a reveni la setarea inițială."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Acum folosiți profilul de serviciu"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Afișați procentajul bateriei încorporat"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 9068e0b..c26f785 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -163,6 +163,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Беззвучный режим."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Удаление приложения <xliff:g id="APP">%s</xliff:g> из списка."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Приложение \"<xliff:g id="APP">%s</xliff:g>\" удалено из списка."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Все недавние приложения закрыты."</string>
@@ -214,6 +216,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Точка доступа отключена."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Точка доступа включена."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Трансляция прекращена."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Яркость экрана"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Передача данных 2G и 3G приостановлена"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Передача данных 4G приостановлена"</string>
@@ -291,6 +301,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Использовано: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Ограничение: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Предупреждение: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Здесь будут показаны недавние приложения"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Сведения о приложении"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"Заблокировать в приложении"</string>
@@ -405,7 +417,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Нет"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"Приложение <xliff:g id="APP_NAME">%1$s</xliff:g> назначено регулятором громкости"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Нажмите, чтобы восстановить приложение по умолчанию."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Вы перешли в рабочий профиль"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Показывать уровень заряда батареи в процентах"</string>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index 3be3718..3ef672a2 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"හඬ නඟනය නිශ්ශබ්දයි."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> ඉවතලන්න."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> අස් කර ඇත."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"සියලුම මෑත යෙඳුම් අස් කරන ලදි."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"ජංගම හොට්ස්පොටය අක්‍රිය කරන ලදි."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"ජංගම හොට්ස්පොටය සක්‍රිය කරන ලදි."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"තිරය විකාශය කිරීම නැවත් වන ලදි."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"දීප්තිය දර්ශනය කරන්න"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G දත්ත විරාම කර ඇත"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G දත්ත විරාම කර ඇත"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> භාවිතා කර තිබේ"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> සීමිත"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> අවවාද කිරීම"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"මෙහි ඔබගේ මෑතක තිර පෙන්නුම් කරයි"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"යෙදුම් තොරතුරු"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"තිර ඇමිණීම"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"ප්‍රතික්ෂේප කරන්න"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ධාරිතා සංවාදයයි"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"මුල් තත්ත්වය නැවත ප්‍රතිසාධනය කිරීමට ස්පර්ශ කරන්න."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ඔබ ඔබේ කාර්යාල පැතිකඩ භාවිත කරමින් සිටී"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"පද්ධති UI සුසරකය"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"කාවද්දන ලද බැටරි ප්‍රතිශතය පෙන්වන්න"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index d96194c..2d6aa9d 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -163,6 +163,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Tiché zvonenie."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Zrušiť aplikáciu <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Aplikácia <xliff:g id="APP">%s</xliff:g> bola zrušená."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Všetky nedávne aplikácie boli odmietnuté."</string>
@@ -214,6 +216,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobilný hotspot je vypnutý."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobilný hotspot je zapnutý."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Prenášanie bolo zastavené."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Jas displeja"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Dátové prenosy 2G a 3G sú pozastavené"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Dátové prenosy 4G sú pozastavené"</string>
@@ -291,6 +301,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Využité: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Limit: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Upozornenie pri <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Vaše nedávne obrazovky sa zobrazia tu."</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informácie o aplikácii"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"pripnutie k obrazovke"</string>
@@ -405,7 +417,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Odmietnuť"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> je dialóg hlasitosti"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Klepnutím obnovíte originál."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Používate svoj pracovný profil."</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Tuner používateľského rozhrania systému"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Zobraziť percentá vloženej batérie"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index f3d3b39..18fa504 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -163,6 +163,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Zvonjenje izklopljeno."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Opusti aplikacijo <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Aplikacija <xliff:g id="APP">%s</xliff:g> je bila odstranjena."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Vse nedavne aplikacije so bile opuščene."</string>
@@ -214,6 +216,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobilna dostopna točka je izklopljena."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobilna dostopna točka je vklopljena."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Predvajanje zaslona je ustavljeno."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Svetlost zaslona"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Prenos podatkov v omrežju 2G/3G je zaustavljen"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Prenos podatkov v omrežju 4G je zaustavljen"</string>
@@ -291,6 +301,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Porabljeno: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Omejitev: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Opozorilo – <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Vaši nedavni zasloni so prikazani tu"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Podatki o aplikaciji"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"pripenjanje zaslona"</string>
@@ -405,7 +417,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Zavrni"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> je pogovorno okno glede prostornine"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Dotaknite se, če želite obnoviti izvirnik."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Uporabljate delovni profil"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Uglaševalnik uporabniškega vmesnika sistema"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Prikaži odstotek napolnjenosti vgraj. akumulatorja"</string>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml
index afad772..ab7e5b0 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Zilja është heshtur."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Largo <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> është hequr."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Të gjitha aplikacionet e fundit u larguan."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Qasja në zona publike interneti është e çaktivizuar."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Zona e qasjes publike për internet është e aktivizuar."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Transmetimi i ekranit ndaloi."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Ndriçimi i ekranit"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Të dhënat 2G-3G janë ndërprerë"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Të dhënat 4G janë ndërprerë"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Të përdorura: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Kufiri: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Paralajmërim për kufirin prej <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Ekranet e tua të fundit shfaqen këtu"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informacioni i aplikacionit"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"gozhdimi i ekranit"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Refuzo"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> është dialogu i volumit"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Prek për të restauruar origjinalin."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Po përdor profilin tënd të punës"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Sintonizuesi i Sistemit të Ndërfaqes së Përdoruesit"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Shfaq përqindjen e baterisë së integruar"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index ad14d26..196d1f1 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -162,6 +162,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Нечујно звоно."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Одбаците <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Апликација <xliff:g id="APP">%s</xliff:g> је одбачена."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Све недавно коришћене апликације су одбачене."</string>
@@ -213,6 +215,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Мобилни хотспот је искључен."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Мобилни хотспот је укључен."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Пребацивање екрана је заустављено."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Осветљеност екрана"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G подаци су паузирани"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G подаци су паузирани"</string>
@@ -290,6 +300,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Искористили сте <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Ограничење од <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Упозорење за <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Недавни екрани се појављују овде"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Информације о апликацији"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"качење екрана"</string>
@@ -404,7 +416,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Одбиј"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> је дијалог за јачину звука"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Додирните да бисте вратили оригинал."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Користите профил за Work"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Тјунер за кориснички интерфејс система"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Приказуј уграђени проценат батерије"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 15e8b12..31066bf 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Tyst ringsignal."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Ta bort <xliff:g id="APP">%s</xliff:g> från listan."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> togs bort permanent."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Alla appar har tagits bort från listan Senaste."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Den mobila trådlösa surfzonen har inaktiverats."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Den mobila trådlösa surfzonen har aktiverats."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Castningen av skärmen har stoppats."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Skärmens ljusstyrka"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G- och 3G-data har pausats"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G-data har pausats"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> används"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Gräns: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Varning <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Dina senaste skärmar visas här"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Appinformation"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fästa skärmen"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Neka"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> används som volymkontroll"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Tryck här om du vill återställa den ursprungliga appen."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Du använder din jobbprofil"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Inställningar för systemgränssnitt"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Visa inbäddad batteriprocent"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 1d231fc..eeeef1f 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Mlio wa simu uko kimya."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Ondoa <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> imeondolewa."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Programu za hivi majuzi zimeondolewa."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mtandao-hewa unaoweza kuhamishika umezimwa."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mtandao-hewa unaoweza kuhamishika umewashwa."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Utumaji wa skrini umesitishwa."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Ung\'aavu wa skrini"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Data ya 2G-3G imesitishwa"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Data ya 4G imesitishwa"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> imetumika"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"kikomo <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Onyo <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Skrini zako za hivi majuzi huonekana hapa"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Maelezo ya Programu"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"kudumisha programu moja"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Kataa"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ni mazungumzo ya sauti"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Gusa ili urejeshe ya awali."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Unatumia wasifu wako wa kazini"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Kipokea Ishara cha SystemUI"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Onyesha asilimia ya betri iliyopachikwa"</string>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index c41494b..a6ad0df 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"ரிங்கர் நிசப்தம்."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> ஐ நிராகரி."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> விலக்கப்பட்டது."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"எல்லா சமீபத்திய பயன்பாடுகளும் விலக்கப்பட்டன."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"மொபைல் ஹாட்ஸ்பாட் முடக்கப்பட்டது."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"மொபைல் ஹாட்ஸ்பாட் இயக்கப்பட்டது."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"திரையை அனுப்புதல் நிறுத்தப்பட்டது."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"திரை பிரகாசம்"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G டேட்டா இடைநிறுத்தப்பட்டது"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G டேட்டா இடைநிறுத்தப்பட்டது"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"பயன்படுத்தியது - <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> வரம்பு"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> எச்சரிக்கை"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"சமீபத்திய திரைகள் இங்கு தோன்றும்"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"பயன்பாட்டு தகவல்"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"திரையை பின் செய்தல்"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"நிராகரி"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"ஒலியளவு செய்தி: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"அசலை மீட்டமைக்கத் தொடவும்."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"பணி சுயவிவரத்தைப் பயன்படுத்துகிறீர்கள்"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"உள்ளிணைந்த பேட்டரி சதவீதத்தைக் காட்டு"</string>
diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml
index a628ef7..468d00d 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"రింగర్ నిశ్శబ్దంలో ఉంది."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>ని తీసివేయండి."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> తీసివేయబడింది."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"అన్ని ఇటీవలి అనువర్తనాలు తీసివేయబడ్డాయి."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"మొబైల్ హాట్‌స్పాట్ ఆఫ్ చేయబడింది."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"మొబైల్ హాట్‌స్పాట్ ఆన్ చేయబడింది."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"స్క్రీన్ ప్రసారం ఆపివేయబడింది."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"ప్రదర్శన ప్రకాశం"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G డేటా పాజ్ చేయబడింది"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G డేటా పాజ్ చేయబడింది"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> వినియోగించబడింది"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> పరిమితి"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> హెచ్చరిక"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"మీ ఇటీవలి స్క్రీన్‌లు ఇక్కడ కనిపిస్తాయి"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"అనువర్తన సమాచారం"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"స్క్రీన్ పిన్నింగ్"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"తిరస్కరించు"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> అనేది వాల్యూమ్ డైలాగ్"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"అసలుదాన్ని పునరుద్ధరించడానికి తాకండి."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"మీరు మీ కార్యాలయ ప్రొఫైల్‌ను ఉపయోగిస్తున్నారు"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"సిస్టమ్ UI ట్యూనర్"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"పొందుపరిచిన బ్యాటరీ శాతం చూపు"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 44ad1fa..130a8bf 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"เสียงเรียกเข้าแบบปิดเสียง"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"ยกเลิก <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ถูกลบไปแล้ว"</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"ปิดแอปพลิเคชันล่าสุดทั้งหมดแล้ว"</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"ปิดฮอตสปอตเคลื่อนที่แล้ว"</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"เปิดฮอตสปอตเคลื่อนที่แล้ว"</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"หยุดการส่งหน้าจอแล้ว"</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"ความสว่างของหน้าจอ"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"หยุดการใช้ข้อมูล 2G-3G ชั่วคราวแล้ว"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"หยุดการใช้ข้อมูล 4G ชั่วคราวแล้ว"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"ใช้ไปแล้ว <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"ขีดจำกัด <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"คำเตือน <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"หน้าจอล่าสุดของคุณแสดงที่นี่"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"ข้อมูลแอปพลิเคชัน"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"การตรึงหน้าจอ"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"ปฏิเสธ"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> เป็นช่องโต้ตอบระดับเสียง"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"แตะเพื่อคืนค่าดั้งเดิม"</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"คุณกำลังใช้โปรไฟล์งานของคุณ"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"ตัวรับสัญญาณ UI ระบบ"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"แสดงเปอร์เซ็นต์ของแบตเตอรี่ในตัว"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index c1bb85c..2546c9e 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Naka-silent ang ringer."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"I-dismiss ang <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Hindi pinansin ang <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Na-dismiss ang lahat ng kamakailang application."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Na-off ang mobile hotspot."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Na-on ang mobile hotspot."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Itinigil ang pagka-cast sa screen."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Liwanag ng display"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Naka-pause ang 2G-3G data"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Naka-pause ang 4G data"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> ang nagamit"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> ang limitasyon"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Babala sa <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Lumalabas dito ang iyong mga kamakailang screen"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Impormasyon ng Application"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"pagpi-pin sa screen"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Tanggihan"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ang volume dialog"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Pindutin upang ibalik ang orihinal."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Ginagamit mo ang iyong profile sa trabaho"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Tuner ng System UI"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Ipakita ang naka-embed na porsyento ng baterya"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 854f850..c9aa1f5 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Telefon zili sessiz."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> uygulamasını kapat."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> kaldırıldı."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Tüm son uygulamalar kapatıldı."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobil hotspot kapatıldı."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobil hotspot açıldı."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Ekran yayını durduruldu."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Ekran parlaklığı"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G veri kullanımı duraklatıldı"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G veri kullanımı duraklatıldı"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> kullanıldı"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Sınır: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> uyarısı"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Son ekranlarınız burada görünür"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Uygulama Bilgileri"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ekran sabitleme"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Reddet"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ses denetimi iletişim kutusu olarak ayarlandı"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Orijinali geri yüklemek için dokunun."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"İş profilinizi kullanıyorsunuz"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Sistem Arayüzü Ayarlayıcısı"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Yerleşik pil yüzdesini göster"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 5347d93..58ae655 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -163,6 +163,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Дзвінок беззвучний."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Видалити додаток <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Програму <xliff:g id="APP">%s</xliff:g> закрито."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Усі останні додатки закрито."</string>
@@ -214,6 +216,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Мобільну точку доступу вимкнено."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Мобільну точку доступу ввімкнено."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Трансляцію екрана зупинено."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Яскравість дисплея"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Передавання даних 2G–3G призупинено"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Передавання даних 4G призупинено"</string>
@@ -291,6 +301,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Використовується: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Обмеження: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Застереження: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Ваші останні екрани відображаються тут"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Інформація про додаток"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"закріпити екран"</string>
@@ -405,7 +417,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Відхилити"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> призначено регулятором гучності"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Торкніться, щоб відновити оригінал."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Ви в робочому профілі"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Показувати заряд акумулятора у відсотках"</string>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index b9da6e3..9d42aad 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"رنگر خاموش۔"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> کو مسترد کریں۔"</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> کو ہٹا دیا گیا۔"</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"سبھی حالیہ ایپلیکیشنز کو برخاست کر دیا گیا۔"</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"موبائل ہاٹ اسپاٹ کو آف کر دیا گیا۔"</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"موبائل ہاٹ اسپاٹ کو آن کر دیا گیا۔"</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"اسکرین کو کاسٹ کرنا بند کر دیا۔"</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"ڈسپلے کی چمک"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"‏2G-3G ڈیٹا موقوف کر دیا گیا"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"‏4G ڈیٹا موقوف کر دیا گیا"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> استعمال کردہ"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> حد"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> وارننگ"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"آپ کی حالیہ اسکرینز یہاں ظاہر ہوتی ہیں"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"ایپلیکیشن کی معلومات"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"اسکرین کو پن کرنا"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"مسترد کریں"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> والیوم ڈائلاگ ہے"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"اصل کو بحال کرنے کیلئے ٹچ کریں۔"</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">"،"</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"آپ اپنا دفتری پروفائل استعمال کر رہے ہیں۔"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"‏سسٹم UI ٹیونر"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"سرایت کردہ بیٹری کی فیصد دکھائیں"</string>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index 67cd123..f7959ea 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Ovozsiz qo‘ng‘iroq."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Olib tashlash: <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> olib tashlangan."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Yaqinda ishlatilgan barcha ilovalar olib tashlandi."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobil ulanish nuqtasi o‘chirildi."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobil ulanish nuqtasi yoqildi."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Ekranni translatsiya qilish to‘xtadi."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Ekran yorqinligi"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G internet to‘xtatib qo‘yildi"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G internet to‘xtatib qo‘yildi"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> foydalanilgan"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Cheklov: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Ogohlantirish: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Siz yaqinda ishlatgan ilova ekranlari bu yerda ko‘rinadi"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Ilova haqida ma’lumot"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"o‘zgarmas ekran"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Rad etish"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ovoz balandligini boshqaradi"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Aslini tiklash uchun bosing."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Siz ishchi profildan foydalanmoqdasiz"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"SystemUI Tuner"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Batareya foizi ko‘rsatilsin"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index aa81068..ffcc73a 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Chuông im lặng."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Xóa bỏ <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> đã bị loại bỏ."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Đã bỏ qua tất cả các ứng dụng gần đây."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Đã tắt điểm phát sóng di động."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Đã bật điểm phát sóng di động."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Đã ngừng truyền màn hình."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Độ sáng màn hình"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Đã tạm dừng dữ liệu 2G-3G"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Đã tạm dừng dữ liệu 4G"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Đã sử dụng <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Giới hạn <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Cảnh báo <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Màn hình gần đây của bạn sẽ xuất hiện tại đây"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Thông tin ứng dụng"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"khóa màn hình"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Từ chối"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> là hộp thoại khối lượng"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Chạm để khôi phục bản gốc."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Bạn đang sử dụng hồ sơ công việc của mình"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Bộ điều hướng giao diện người dùng hệ thống"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Hiển thị tỷ lệ phần trăm pin được nhúng"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index fa69975..2d8dd2a 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"振铃器静音。"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"移除<xliff:g id="APP">%s</xliff:g>。"</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"已删除<xliff:g id="APP">%s</xliff:g>"</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"已关闭所有最近用过的应用。"</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"移动热点已关闭。"</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"移动热点已开启。"</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"屏幕投射已停止。"</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"屏幕亮度"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G 数据网络已暂停使用"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G 数据网络已暂停使用"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"已使用<xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"上限为<xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g>警告"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"您最近浏览过的屏幕会显示在此处"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"应用信息"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"固定屏幕"</string>
@@ -326,8 +338,8 @@
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"仅限\n优先打扰"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"仅限\n闹钟"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"正在充电(还需<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>充满)"</string>
-    <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"正在快速充电(还需 <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>才能充满)"</string>
-    <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"正在慢速充电(还需 <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>才能充满)"</string>
+    <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"正在快速充电(还需<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>充满)"</string>
+    <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"正在慢速充电(还需<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>充满)"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"切换用户"</string>
     <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"切换用户,当前用户为<xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"当前用户为<xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"拒绝"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”已用作音量控制对话框"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"触摸即可恢复原始设置。"</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">"、"</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"您当前正在使用工作资料"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"系统界面调谐器"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"嵌入式显示电池电量百分比 显示嵌入的电池电量百分比"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 7375a92..569d847 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"鈴聲靜音。"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"關閉「<xliff:g id="APP">%s</xliff:g>」。"</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"「<xliff:g id="APP">%s</xliff:g>」已關閉。"</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"所有最近使用的應用程式均已關閉。"</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"流動熱點已關閉。"</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"流動熱點已開啟。"</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"已停止投放螢幕。"</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"顯示光暗度"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"已暫停 2G-3G 數據"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"已暫停 4G 數據"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"已使用 <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"上限為 <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> 警告"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"您最近的螢幕顯示在這裡"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"應用程式資料"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"螢幕固定"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"拒絕"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」為音量對話框"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"輕觸即可復原。"</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">"、"</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"您正在使用工作設定檔"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"系統使用者介面調諧器"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"顯示嵌入的電池百分比"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 5edda84..f2ffe16 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"鈴聲靜音。"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"關閉「<xliff:g id="APP">%s</xliff:g>」。"</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"「<xliff:g id="APP">%s</xliff:g>」已關閉。"</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"最近使用的應用程式已全部關閉。"</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"可攜式無線基地台已關閉。"</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"可攜式無線基地台已開啟。"</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"已停止投放螢幕。"</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"螢幕亮度"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"已暫停 2G-3G 數據連線"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"已暫停 4G 數據連線"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"已使用 <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"上限為 <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> 警告"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"您最近的螢幕會顯示在這裡"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"應用程式資訊"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"螢幕固定"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"拒絕"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」現在是預設的音量控制對話方塊。"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"輕觸這裡即可恢復原始設定。"</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">"、"</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"您正在使用 Work 設定檔"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"系統使用者介面調整精靈"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"顯示嵌入式電池百分比"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 51c4389..efa04e6 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -161,6 +161,8 @@
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Isikhali sithulile."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
+    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
+    <skip />
     <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Cashisa i-<xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ivaliwe."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Zonke izinhlelo zokusebenza zakamuva zicashisiwe."</string>
@@ -212,6 +214,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"I-hotspot ivaliwe."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"I-hotspot ivuliwe."</string>
     <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Ukusakaza kwesikrini kumisiwe."</string>
+    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
+    <skip />
+    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
+    <skip />
     <string name="accessibility_brightness" msgid="8003681285547803095">"Bonisa ukukhanya"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G idatha imisiwe"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G idatha imisiwe"</string>
@@ -289,6 +299,8 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> isetshenzisiwe"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> umkhawulo"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> isexwayiso"</string>
+    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
+    <skip />
     <string name="recents_empty_message" msgid="8682129509540827999">"Izikrini zakho zakamuva zivela lapha"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Ulwazi lohlelo lokusebenza"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ukuphina isikrini"</string>
@@ -403,7 +415,8 @@
     <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Phika"</string>
     <string name="volumeui_notification_title" msgid="4906770126345910955">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> yingxoxo yevolumu"</string>
     <string name="volumeui_notification_text" msgid="1826889705095768656">"Thinta ukuze ubuyisele kokwangempela."</string>
-    <string name="group_summary_concadenation" msgid="2705151242008937028">","</string>
+    <!-- no translation found for group_summary_concadenation (6846402378100148789) -->
+    <skip />
     <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Usebenzisa iphrofayela yakho yomsebenzi"</string>
     <string name="system_ui_tuner" msgid="708224127392452018">"Isishuni se-UI yesistimu"</string>
     <string name="show_battery_percentage" msgid="5444136600512968798">"Bonisa amaphesenti ebhethri elinamathiselwe"</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 5618e9b..8875515 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -68,6 +68,8 @@
     <color name="recents_task_view_lock_to_app_button_background_color">#ffe6e6e6</color>
     <!-- The lock to task button foreground color. -->
     <color name="recents_task_view_lock_to_app_button_color">#ff666666</color>
+    <!-- The background color for the freeform workspace. -->
+    <color name="recents_freeform_workspace_bg_color">#66000000</color>
 
     <color name="keyguard_affordance">#ffffffff</color>
 
@@ -144,4 +146,7 @@
 
     <color name="docked_divider_background">#ff000000</color>
     <color name="docked_divider_handle">#ffffff</color>
+
+    <color name="default_remote_input_background">@*android:color/notification_default_color</color>
+    <color name="remote_input_hint">#4dffffff</color>
 </resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index a0052ce..40e8b50 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -103,7 +103,7 @@
 
     <!-- The default tiles to display in QuickSettings -->
     <string name="quick_settings_tiles_default" translatable="false">
-        wifi,bt,inversion,dnd,cell,airplane,rotation,flashlight,location,cast,hotspot
+        wifi,bt,flashlight,dnd,cell,battery,rotation,airplane,location,cast
     </string>
 
     <!-- The tiles to display in QuickSettings -->
@@ -117,7 +117,7 @@
     <integer name="quick_settings_brightness_dialog_long_timeout">4000</integer>
 
     <!-- The maximum number of items to be displayed in quick settings -->
-    <integer name="quick_settings_detail_max_item_count">7</integer>
+    <integer name="quick_settings_detail_max_item_count">5</integer>
 
     <!-- Should "4G" be shown instead of "LTE" when the network is NETWORK_TYPE_LTE? -->
     <bool name="config_show4GForLTE">true</bool>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 086e9f4..4f070d6 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -36,18 +36,6 @@
     <!-- The font size for the clock -->
     <dimen name="status_bar_clock_size">14sp</dimen>
 
-    <!-- The margin on the start of the content view -->
-    <dimen name="notification_content_margin_start">16dp</dimen>
-
-    <!-- The maximum size of the title when in single line mode -->
-    <dimen name="notification_maximum_title_length">150sp</dimen>
-
-    <!-- The margin on the end of the content view -->
-    <dimen name="notification_content_margin_end">8dp</dimen>
-
-    <!-- Height of a single line notification in the status bar -->
-    <dimen name="notification_single_line_height">32sp</dimen>
-
     <!-- Height of a small notification in the status bar-->
     <dimen name="notification_min_height">84dp</dimen>
 
@@ -57,8 +45,11 @@
     <!-- Height of a large notification in the status bar -->
     <dimen name="notification_max_height">276dp</dimen>
 
-    <!-- Height of a medium notification in the status bar -->
-    <dimen name="notification_mid_height">128dp</dimen>
+    <!-- Height of a heads up notification in the status bar for legacy custom views -->
+    <dimen name="notification_max_heads_up_height_legacy">128dp</dimen>
+
+    <!-- Height of a heads up notification in the status bar -->
+    <dimen name="notification_max_heads_up_height">140dp</dimen>
 
     <!-- Height of a the summary ("more card") notification on keyguard. -->
     <dimen name="notification_summary_height">44dp</dimen>
@@ -107,7 +98,7 @@
     <dimen name="close_handle_underlap">32dp</dimen>
 
     <!-- Height of the status bar header bar -->
-    <dimen name="status_bar_header_height">60dp</dimen>
+    <dimen name="status_bar_header_height">90dp</dimen>
 
     <!-- Height of the status bar header bar when expanded -->
     <dimen name="status_bar_header_height_expanded">116dp</dimen>
@@ -145,6 +136,7 @@
     <dimen name="qs_quick_actions_padding">25dp</dimen>
     <dimen name="qs_quick_tile_size">48dp</dimen>
     <dimen name="qs_quick_tile_padding">12dp</dimen>
+    <dimen name="qs_date_anim_translation">44.5dp</dimen>
     <dimen name="qs_page_indicator_size">12dp</dimen>
     <dimen name="qs_tile_icon_size">24dp</dimen>
     <dimen name="qs_tile_text_size">12sp</dimen>
@@ -173,7 +165,7 @@
     <dimen name="borderless_button_radius">2dp</dimen>
 
     <!-- How far the expanded QS panel peeks from the header in collapsed state. -->
-    <dimen name="qs_peek_height">8dp</dimen>
+    <dimen name="qs_peek_height">0dp</dimen>
 
     <!-- Zen mode panel: condition item button padding -->
     <dimen name="zen_mode_condition_detail_button_padding">8dp</dimen>
@@ -351,8 +343,11 @@
     <!-- radius of the corners of the material rounded rect background but negative-->
     <dimen name="notification_material_rounded_rect_radius_negative">-2dp</dimen>
 
-    <!-- The padding between notification children -->
-    <dimen name="notification_children_padding">2dp</dimen>
+    <!-- The padding between notification children when collapsed -->
+    <dimen name="notification_children_padding">4dp</dimen>
+
+    <!-- The padding on top of the first notification to the children container -->
+    <dimen name="notification_children_container_top_padding">8dp</dimen>
 
     <!-- The height of the divider between the notfication children -->
     <dimen name="notification_children_divider_height">1dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 002b9f5..666a024 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -401,6 +401,9 @@
     <!-- Content description of the cast icon in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_casting">@string/quick_settings_casting</string>
 
+    <!-- Content description of the work mode icon in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_work_mode">Work mode</string>
+
     <!-- Content description to tell the user that this button will remove an application from recents -->
     <string name="accessibility_recents_item_will_be_dismissed">Dismiss <xliff:g id="app" example="Calendar">%s</xliff:g>.</string>
     <!-- Content description to tell the user an application has been removed from recents -->
@@ -505,6 +508,14 @@
     <string name="accessibility_quick_settings_hotspot_changed_on">Mobile hotspot turned on.</string>
     <!-- Announcement made when the screen stopped casting (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_casting_turned_off">Screen casting stopped.</string>
+    <!-- Content description of the work mode title in quick settings when off (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_work_mode_off">Work mode off.</string>
+    <!-- Content description of the work mode title in quick settings when on (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_work_mode_on">Work mode on.</string>
+    <!-- Announcement made when the work mode changes to off (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_work_mode_changed_off">Work mode turned off.</string>
+    <!-- Announcement made when the work mode changes to on (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_work_mode_changed_on">Work mode turned on.</string>
 
     <!-- Content description of the display brightness slider (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_brightness">Display brightness</string>
@@ -687,6 +698,8 @@
     <string name="quick_settings_cellular_detail_data_limit"><xliff:g id="data_limit" example="2.0 GB">%s</xliff:g> limit</string>
     <!-- QuickSettings: Cellular detail panel, data warning format string [CHAR LIMIT=NONE] -->
     <string name="quick_settings_cellular_detail_data_warning"><xliff:g id="data_limit" example="2.0 GB">%s</xliff:g> warning</string>
+    <!-- QuickSettings: Work mode [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_work_mode_label">Work mode</string>
 
     <!-- Recents: The empty recents string. [CHAR LIMIT=NONE] -->
     <string name="recents_empty_message">Your recent screens appear here</string>
@@ -1025,8 +1038,8 @@
     <!-- VolumeUI restoration notification: text -->
     <string name="volumeui_notification_text">Touch to restore the original.</string>
 
-    <!-- Describes the way 2 names are concatenated. An example would be ", " to produce "Peter Muller, Paul Curry". Please also include a space here if it's appropriate in the language and if it's a RTL language include it on the left. [CHAR LIMIT=3] -->
-    <string name="group_summary_concadenation">, </string>
+    <!-- Describes the way 2 names are concatenated. An example would be ", " to produce "Peter Muller, Paul Curry". Please also include a space here if it's appropriate in the language and if it's a RTL language include it on the left. The translation should start and end with " to keep the white space if desired [CHAR LIMIT=5] -->
+    <string name="group_summary_concadenation">", "</string>
 
     <!-- Toast shown when user unlocks screen and managed profile activity is in the foreground -->
     <string name="managed_profile_foreground_toast">You\'re using your work profile</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 2fd0fe5..47ad6dc 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -311,6 +311,8 @@
 
     <style name="DockedDividerHandle">
         <item name="android:layout_gravity">center_horizontal</item>
+        <item name="android:layout_width">64dp</item>
+        <item name="android:layout_height">48dp</item>
     </style>
 
 </resources>
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index 8dcf8a7..e31927e 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -18,25 +18,10 @@
     xmlns:sysui="http://schemas.android.com/apk/res-auto"
     android:title="@string/system_ui_tuner">
 
-    <PreferenceScreen
-        android:title="@string/quick_settings">
-
-        <PreferenceCategory
-            android:title="@string/experimental">
-
-            <com.android.systemui.tuner.TunerSwitch
-                android:key="qs_show_brightness"
-                android:title="@string/show_brightness"
-                sysui:defValue="true" />
-
-            <com.android.systemui.tuner.QSPagingSwitch
-                android:key="qs_paged_panel"
-                android:title="@string/qs_paging" />
-
-        </PreferenceCategory>
-
-    </PreferenceScreen>
-
+    <com.android.systemui.tuner.TunerSwitch
+        android:key="qs_show_brightness"
+        android:title="@string/show_brightness"
+        sysui:defValue="true" />
 
     <PreferenceScreen
         android:title="@string/status_bar" >
diff --git a/packages/SystemUI/src/com/android/systemui/QSQuickTileView.java b/packages/SystemUI/src/com/android/systemui/QSQuickTileView.java
deleted file mode 100644
index 3362650..0000000
--- a/packages/SystemUI/src/com/android/systemui/QSQuickTileView.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui;
-
-import android.content.Context;
-import android.view.View;
-import android.widget.ImageView;
-import com.android.systemui.qs.QSTile;
-import com.android.systemui.qs.QSTileBaseView;
-
-public class QSQuickTileView extends QSTileBaseView {
-
-    private final int mPadding;
-    private final ImageView mIcon;
-
-    public QSQuickTileView(Context context) {
-        super(context);
-        mPadding = context.getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_padding);
-        mIcon = createIcon();
-        addView(mIcon);
-    }
-
-    protected ImageView createIcon() {
-        final ImageView icon = new ImageView(mContext);
-        icon.setId(android.R.id.icon);
-        icon.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
-        return icon;
-    }
-
-    @Override
-    public void init(OnClickListener click, OnClickListener clickSecondary,
-                     OnLongClickListener longClick) {
-        setClickable(true);
-        setOnClickListener(click);
-    }
-
-    @Override
-    protected void handleStateChanged(QSTile.State state) {
-        mIcon.setImageDrawable(state.icon.getDrawable(getContext()));
-        setContentDescription(state.contentDescription);
-    }
-
-    @Override
-    public boolean setType(int type) {
-        return false;
-    }
-
-    @Override
-    public View updateAccessibilityOrder(View previousView) {
-        return this;
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        mIcon.measure(exactly(getMeasuredWidth() - 2 * mPadding),
-                exactly(getMeasuredHeight() - 2 * mPadding));
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        layout(mIcon, mPadding, mPadding);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/ViewInvertHelper.java b/packages/SystemUI/src/com/android/systemui/ViewInvertHelper.java
index 5b8d3d6..c9ba885 100644
--- a/packages/SystemUI/src/com/android/systemui/ViewInvertHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ViewInvertHelper.java
@@ -19,6 +19,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
+import android.content.Context;
 import android.graphics.ColorMatrix;
 import android.graphics.ColorMatrixColorFilter;
 import android.graphics.Paint;
@@ -35,13 +36,19 @@
 
     private final Paint mDarkPaint = new Paint();
     private final Interpolator mLinearOutSlowInInterpolator;
-    private final ArrayList<View> mTargets;
     private final ColorMatrix mMatrix = new ColorMatrix();
     private final ColorMatrix mGrayscaleMatrix = new ColorMatrix();
     private final long mFadeDuration;
+    private final ArrayList<View> mTargets = new ArrayList<>();
 
-    public ViewInvertHelper(View target, long fadeDuration) {
-        this(constructArray(target), fadeDuration);
+    public ViewInvertHelper(View v, long fadeDuration) {
+        this(v.getContext(), fadeDuration);
+        addTarget(v);
+    }
+    public ViewInvertHelper(Context context, long fadeDuration) {
+        mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
+                android.R.interpolator.linear_out_slow_in);
+        mFadeDuration = fadeDuration;
     }
 
     private static ArrayList<View> constructArray(View target) {
@@ -50,11 +57,12 @@
         return views;
     }
 
-    public ViewInvertHelper(ArrayList<View> targets, long fadeDuration) {
-        mTargets = targets;
-        mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(mTargets.get(0).getContext(),
-                android.R.interpolator.linear_out_slow_in);
-        mFadeDuration = fadeDuration;
+    public void clearTargets() {
+        mTargets.clear();
+    }
+
+    public void addTarget(View target) {
+        mTargets.add(target);
     }
 
     public void fade(final boolean invert, long delay) {
@@ -112,4 +120,12 @@
         mMatrix.preConcat(mGrayscaleMatrix);
         mDarkPaint.setColorFilter(new ColorMatrixColorFilter(mMatrix));
     }
+
+    public void setInverted(boolean invert, boolean fade, long delay) {
+        if (fade) {
+            fade(invert, delay);
+        } else {
+            update(invert);
+        }
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index 0e4a4e5..ca4a03a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -73,11 +73,6 @@
     }
 
     @Override
-    public void setTileVisibility(TileRecord tile, int visibility) {
-        tile.tileView.setVisibility(visibility);
-    }
-
-    @Override
     public void addTile(TileRecord tile) {
         mTiles.add(tile);
         distributeTiles();
@@ -101,10 +96,6 @@
         final int NT = mTiles.size();
         for (int i = 0; i < NT; i++) {
             TileRecord tile = mTiles.get(i);
-            if (tile.tile.getTileType() == QSTileView.QS_TYPE_QUICK) {
-                // Don't show any quick tiles for now.
-                continue;
-            }
             if (mPages.get(index).isFull()) {
                 if (++index == mPages.size()) {
                     if (DEBUG) Log.d(TAG, "Adding page for " + tile.tile.getClass().getSimpleName());
@@ -178,7 +169,6 @@
 
         public TilePage(Context context, AttributeSet attrs) {
             super(context, attrs);
-            mAllowDual = false;
             updateResources();
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PseudoGridView.java b/packages/SystemUI/src/com/android/systemui/qs/PseudoGridView.java
index cb6708e..699273a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PseudoGridView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PseudoGridView.java
@@ -98,7 +98,7 @@
             }
         }
 
-        setMeasuredDimension(width, getDefaultSize(totalHeight, heightMeasureSpec));
+        setMeasuredDimension(width, resolveSizeAndState(totalHeight, heightMeasureSpec, 0));
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java b/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java
new file mode 100644
index 0000000..b56ad76
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java
@@ -0,0 +1,104 @@
+/*
+ * 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.qs;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.drawable.Animatable;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import com.android.systemui.R;
+
+import java.util.Objects;
+
+public class QSIconView extends ViewGroup {
+
+    private final View mIcon;
+    private final int mIconSizePx;
+    private final int mTilePaddingBelowIconPx;
+
+    public QSIconView(Context context) {
+        super(context);
+
+        final Resources res = context.getResources();
+        mIconSizePx = res.getDimensionPixelSize(R.dimen.qs_tile_icon_size);
+        mTilePaddingBelowIconPx =  res.getDimensionPixelSize(R.dimen.qs_tile_padding_below_icon);
+
+        mIcon = createIcon();
+        addView(mIcon);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        final int w = MeasureSpec.getSize(widthMeasureSpec);
+        final int iconSpec = exactly(mIconSizePx);
+        mIcon.measure(MeasureSpec.makeMeasureSpec(w, getIconMeasureMode()), iconSpec);
+        setMeasuredDimension(w, mIcon.getMeasuredHeight() + mTilePaddingBelowIconPx);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        final int w = getMeasuredWidth();
+        final int h = getMeasuredHeight();
+        int top = 0;
+        final int iconLeft = (w - mIcon.getMeasuredWidth()) / 2;
+        layout(mIcon, iconLeft, top);
+    }
+
+    public void setIcon(QSTile.State state) {
+        setIcon((ImageView) mIcon, state);
+    }
+
+    protected void setIcon(ImageView iv, QSTile.State state) {
+        if (!Objects.equals(state.icon, iv.getTag(R.id.qs_icon_tag))) {
+            Drawable d = state.icon != null ? state.icon.getDrawable(mContext) : null;
+            if (d != null && state.autoMirrorDrawable) {
+                d.setAutoMirrored(true);
+            }
+            iv.setImageDrawable(d);
+            iv.setTag(R.id.qs_icon_tag, state.icon);
+            if (d instanceof Animatable) {
+                Animatable a = (Animatable) d;
+                if (state.icon instanceof QSTile.AnimationIcon && !iv.isShown()) {
+                    a.stop(); // skip directly to end state
+                }
+            }
+        }
+
+    }
+
+    protected int getIconMeasureMode() {
+        return MeasureSpec.EXACTLY;
+    }
+
+    protected View createIcon() {
+        final ImageView icon = new ImageView(mContext);
+        icon.setId(android.R.id.icon);
+        icon.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
+        return icon;
+    }
+
+    protected static int exactly(int size) {
+        return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
+    }
+
+    protected static void layout(View child, int left, int top) {
+        child.layout(left, top, left + child.getMeasuredWidth(), top + child.getMeasuredHeight());
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index bb2b8fc..ae8542a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -19,14 +19,12 @@
 import android.animation.Animator;
 import android.animation.Animator.AnimatorListener;
 import android.animation.AnimatorListenerAdapter;
-import android.app.ActivityManager;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.os.Handler;
 import android.os.Message;
-import android.provider.Settings;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -36,7 +34,6 @@
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
-
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
@@ -56,7 +53,6 @@
 public class QSPanel extends FrameLayout implements Tunable {
 
     public static final String QS_SHOW_BRIGHTNESS = "qs_show_brightness";
-    public static final String QS_THE_NEW_QS = "qs_paged_panel";
 
     protected final Context mContext;
     protected final ArrayList<TileRecord> mRecords = new ArrayList<TileRecord>();
@@ -102,20 +98,25 @@
         updateDetailText();
         mDetail.setVisibility(GONE);
         mDetail.setClickable(true);
-        mBrightnessView = LayoutInflater.from(context).inflate(
-                R.layout.quick_settings_brightness_dialog, this, false);
-        mFooter = new QSFooter(this, context);
         addView(mDetail);
 
         mQsContainer = new LinearLayout(mContext);
         mQsContainer.setOrientation(LinearLayout.VERTICAL);
         mQsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
                 LayoutParams.WRAP_CONTENT));
-
         addView(mQsContainer);
 
+        mBrightnessView = LayoutInflater.from(context).inflate(
+                R.layout.quick_settings_brightness_dialog, this, false);
         mQsContainer.addView(mBrightnessView);
+
+        mTileLayout = (QSTileLayout) LayoutInflater.from(mContext).inflate(
+                R.layout.qs_paged_tile_layout, mQsContainer, false);
+        mQsContainer.addView((View) mTileLayout);
+
+        mFooter = new QSFooter(this, context);
         mQsContainer.addView(mFooter.getView());
+
         mClipper = new QSDetailClipper(mDetail);
         updateResources();
 
@@ -136,7 +137,7 @@
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
-        TunerService.get(mContext).addTunable(this, QS_SHOW_BRIGHTNESS, QS_THE_NEW_QS);
+        TunerService.get(mContext).addTunable(this, QS_SHOW_BRIGHTNESS);
     }
 
     @Override
@@ -150,36 +151,15 @@
         if (QS_SHOW_BRIGHTNESS.equals(key)) {
             mBrightnessView.setVisibility(newValue == null || Integer.parseInt(newValue) != 0
                     ? VISIBLE : GONE);
-        } else if (QS_THE_NEW_QS.equals(key)) {
-            boolean theNewQs = newValue != null && Integer.parseInt(newValue) != 0;
-            if (mTileLayout != null) {
-                for (int i = 0; i < mRecords.size(); i++) {
-                    mTileLayout.removeTile(mRecords.get(i));
-                }
-                mQsContainer.removeView((View) mTileLayout);
-            }
-            int layout = theNewQs
-                    ? R.layout.qs_paged_tile_layout : R.layout.qs_tile_layout;
-            mTileLayout =
-                    (QSTileLayout) LayoutInflater.from(mContext).inflate(layout, mQsContainer, false);
-            mQsContainer.addView((View) mTileLayout, 1 /* Between brightness and footer */);
-            for (int i = 0; i < mRecords.size(); i++) {
-                mTileLayout.addTile(mRecords.get(i));
-            }
-            if (theNewQs) {
-                mCustomizePanel = (QSCustomizer) LayoutInflater.from(mContext)
-                        .inflate(R.layout.qs_customize_panel, null);
-                mCustomizePanel.setHost(mHost);
-            } else {
-                if (mCustomizePanel != null && mCustomizePanel.isCustomizing()) {
-                    mCustomizePanel.hide(mCustomizePanel.getWidth() / 2,
-                            mCustomizePanel.getHeight() / 2);
-                }
-                mCustomizePanel = null;
-            }
         }
     }
 
+    protected void createCustomizePanel() {
+        mCustomizePanel = (QSCustomizer) LayoutInflater.from(mContext)
+                .inflate(R.layout.qs_customize_panel, null);
+        mCustomizePanel.setHost(mHost);
+    }
+
     private void updateDetailText() {
         mDetailDoneButton.setText(R.string.quick_settings_done);
         mDetailSettingsButton.setText(R.string.quick_settings_more_settings);
@@ -200,6 +180,7 @@
     public void setHost(QSTileHost host) {
         mHost = host;
         mFooter.setHost(host);
+        createCustomizePanel();
     }
 
     public QSTileHost getHost() {
@@ -298,19 +279,10 @@
         showDetail(show, r);
     }
 
-    private void showDetail(boolean show, Record r) {
+    protected void showDetail(boolean show, Record r) {
         mHandler.obtainMessage(H.SHOW_DETAIL, show ? 1 : 0, 0, r).sendToTarget();
     }
 
-    private void setTileVisibility(TileRecord record, int visibility) {
-        mHandler.obtainMessage(H.SET_TILE_VISIBILITY, visibility, 0, record).sendToTarget();
-    }
-
-    private void handleSetTileVisibility(TileRecord tile, int visibility) {
-        if (visibility == tile.tileView.getVisibility()) return;
-        mTileLayout.setTileVisibility(tile, visibility);
-    }
-
     public void setTiles(Collection<QSTile<?>> tiles) {
         for (TileRecord record : mRecords) {
             mTileLayout.removeTile(record);
@@ -325,16 +297,17 @@
     }
 
     private void drawTile(TileRecord r, QSTile.State state) {
-        final int visibility = state.visible ? VISIBLE : GONE;
-        setTileVisibility(r, visibility);
         r.tileView.onStateChanged(state);
     }
 
+    protected QSTileBaseView createTileView(QSTile<?> tile) {
+        return new QSTileView(mContext, tile.createTileView(mContext));
+    }
+
     protected void addTile(final QSTile<?> tile) {
         final TileRecord r = new TileRecord();
         r.tile = tile;
-        r.tileView = tile.createTileView(mContext);
-        r.tileView.setVisibility(View.GONE);
+        r.tileView = createTileView(tile);
         final QSTile.Callback callback = new QSTile.Callback() {
             @Override
             public void onStateChanged(QSTile.State state) {
@@ -369,13 +342,7 @@
         final View.OnClickListener click = new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                r.tile.click();
-            }
-        };
-        final View.OnClickListener clickSecondary = new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                r.tile.secondaryClick();
+                onTileClick(r.tile);
             }
         };
         final View.OnLongClickListener longClick = new View.OnLongClickListener() {
@@ -396,7 +363,7 @@
                 return true;
             }
         };
-        r.tileView.init(click, clickSecondary, longClick);
+        r.tileView.init(click, longClick);
         r.tile.setListening(mListening);
         callback.onStateChanged(r.tile.getState());
         r.tile.refreshState();
@@ -407,6 +374,10 @@
         }
     }
 
+    protected void onTileClick(QSTile<?> tile) {
+        tile.click();
+    }
+
     public boolean isShowingDetail() {
         return mDetailRecord != null
                 || (mCustomizePanel != null && mCustomizePanel.isCustomizing());
@@ -429,7 +400,7 @@
         return mQsContainer.getMeasuredHeight();
     }
 
-    private void handleShowDetail(Record r, boolean show) {
+    protected void handleShowDetail(Record r, boolean show) {
         if (r instanceof TileRecord) {
             handleShowDetailTile((TileRecord) r, show);
         } else {
@@ -515,9 +486,7 @@
     private void logTiles() {
         for (int i = 0; i < mRecords.size(); i++) {
             TileRecord tileRecord = mRecords.get(i);
-            if (tileRecord.tile.getState().visible) {
-                MetricsLogger.visible(mContext, tileRecord.tile.getMetricsCategory());
-            }
+            MetricsLogger.visible(mContext, tileRecord.tile.getMetricsCategory());
         }
     }
 
@@ -554,13 +523,11 @@
         public void handleMessage(Message msg) {
             if (msg.what == SHOW_DETAIL) {
                 handleShowDetail((Record)msg.obj, msg.arg1 != 0);
-            } else if (msg.what == SET_TILE_VISIBILITY) {
-                handleSetTileVisibility((TileRecord) msg.obj, msg.arg1);
             }
         }
     }
 
-    private static class Record {
+    protected static class Record {
         View detailView;
         DetailAdapter detailAdapter;
         int x;
@@ -619,13 +586,7 @@
     public interface QSTileLayout {
         void addTile(TileRecord tile);
         void removeTile(TileRecord tile);
-        void setTileVisibility(TileRecord tile, int visibility);
         int getOffsetTop(TileRecord tile);
         void updateResources();
     }
-
-    public static boolean isTheNewQS(Context context) {
-        return Settings.Secure.getIntForUser(context.getContentResolver(), QS_THE_NEW_QS,
-                ActivityManager.getCurrentUser(), 0) != 0;
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index 7f45545..39f0c55 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -86,20 +86,12 @@
         mTileSpec = tileSpec;
     }
 
-    public int getTileType() {
-        return QSTileView.QS_TYPE_NORMAL;
-    }
-
-    public final boolean supportsDualTargets() {
-        return getTileType() == QSTileView.QS_TYPE_DUAL;
-    }
-
     public Host getHost() {
         return mHost;
     }
 
-    public QSTileBaseView createTileView(Context context) {
-        return new QSTileView(context);
+    public QSIconView createTileView(Context context) {
+        return new QSIconView(context);
     }
 
     public DetailAdapter getDetailAdapter() {
@@ -181,7 +173,8 @@
     }
 
     protected void handleSecondaryClick() {
-        // optional
+        // Default to normal click.
+        handleClick();
     }
 
     protected void handleLongClick() {
@@ -327,8 +320,10 @@
     public interface Host {
         void startActivityDismissingKeyguard(Intent intent);
         void startActivityDismissingKeyguard(PendingIntent intent);
+        void startRunnableDismissingKeyguard(Runnable runnable);
         void warn(String message, Throwable t);
         void collapsePanels();
+        void openPanels();
         Looper getLooper();
         Context getContext();
         Collection<QSTile<?>> getTiles();
@@ -345,6 +340,7 @@
         UserSwitcherController getUserSwitcherController();
         UserInfoController getUserInfoController();
         BatteryController getBatteryController();
+        void removeTile(String tileSpec);
 
         public interface Callback {
             void onTilesChanged();
@@ -451,7 +447,6 @@
     }
 
     public static class State {
-        public boolean visible;
         public Icon icon;
         public CharSequence label;
         public CharSequence contentDescription;
@@ -461,14 +456,12 @@
         public boolean copyTo(State other) {
             if (other == null) throw new IllegalArgumentException();
             if (!other.getClass().equals(getClass())) throw new IllegalArgumentException();
-            final boolean changed = other.visible != visible
-                    || !Objects.equals(other.icon, icon)
+            final boolean changed = !Objects.equals(other.icon, icon)
                     || !Objects.equals(other.label, label)
                     || !Objects.equals(other.contentDescription, contentDescription)
                     || !Objects.equals(other.autoMirrorDrawable, autoMirrorDrawable)
                     || !Objects.equals(other.dualLabelContentDescription,
                     dualLabelContentDescription);
-            other.visible = visible;
             other.icon = icon;
             other.label = label;
             other.contentDescription = contentDescription;
@@ -484,7 +477,6 @@
 
         protected StringBuilder toStringBuilder() {
             final StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('[');
-            sb.append("visible=").append(visible);
             sb.append(",icon=").append(icon);
             sb.append(",label=").append(label);
             sb.append(",contentDescription=").append(contentDescription);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java
index 72fc88d..68461f5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileBaseView.java
@@ -1,57 +1,112 @@
 /*
  * 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
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.qs;
 
 import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.RippleDrawable;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.util.AttributeSet;
 import android.view.View;
-import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import com.android.systemui.R;
 
-public abstract class QSTileBaseView extends ViewGroup {
-
-    public static final int QS_TYPE_NORMAL = 0;
-    public static final int QS_TYPE_DUAL   = 1;
-    public static final int QS_TYPE_QUICK  = 2;
+public class QSTileBaseView extends LinearLayout {
 
     private final H mHandler = new H();
+    private QSIconView mIcon;
+    private RippleDrawable mRipple;
+    private Drawable mTileBackground;
 
-    public QSTileBaseView(Context context) {
+    public QSTileBaseView(Context context, QSIconView icon) {
         super(context);
+        mIcon = icon;
+        addView(mIcon);
+
+        mTileBackground = newTileBackground();
+        if (mTileBackground instanceof RippleDrawable) {
+            setRipple((RippleDrawable) mTileBackground);
+        }
+        setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+        setBackground(mTileBackground);
+
+        // Default to Quick Tile padding, and QSTileView will specify its own padding.
+        int padding = context.getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_padding);
+        setPadding(padding, padding, padding, padding);
     }
 
-    public QSTileBaseView(Context context, AttributeSet attrs) {
-        super(context, attrs);
+    private Drawable newTileBackground() {
+        final int[] attrs = new int[] { android.R.attr.selectableItemBackgroundBorderless };
+        final TypedArray ta = mContext.obtainStyledAttributes(attrs);
+        final Drawable d = ta.getDrawable(0);
+        ta.recycle();
+        return d;
     }
 
+    private void setRipple(RippleDrawable tileBackground) {
+        mRipple = tileBackground;
+        if (getWidth() != 0) {
+            updateRippleSize(getWidth(), getHeight());
+        }
+    }
+
+    private void updateRippleSize(int width, int height) {
+        // center the touch feedback on the center of the icon, and dial it down a bit
+        final int cx = width / 2;
+        final int cy = height / 2;
+        final int rad = (int)(mIcon.getHeight() * .85f);
+        mRipple.setHotspotBounds(cx - rad, cy - rad, cx + rad, cy + rad);
+    }
+
+    public void init(OnClickListener click, OnLongClickListener longClick) {
+        setClickable(true);
+        setOnClickListener(click);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        super.onLayout(changed, l, t, r, b);
+        final int w = getMeasuredWidth();
+        final int h = getMeasuredHeight();
+
+        if (mRipple != null) {
+            updateRippleSize(w, h);
+        }
+    }
+
+    /**
+     * Update the accessibility order for this view.
+     *
+     * @param previousView the view which should be before this one
+     * @return the last view in this view which is accessible
+     */
+    public View updateAccessibilityOrder(View previousView) {
+        setAccessibilityTraversalAfter(previousView.getId());
+        return this;
+    }
 
     public void onStateChanged(QSTile.State state) {
         mHandler.obtainMessage(H.STATE_CHANGED, state).sendToTarget();
     }
 
-    public abstract void init(OnClickListener click, OnClickListener clickSecondary,
-                              OnLongClickListener longClick);
-    public abstract View updateAccessibilityOrder(View previousView);
-    public abstract boolean setType(int type);
-
-    protected abstract void handleStateChanged(QSTile.State state);
-
-    protected static int exactly(int size) {
-        return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
-    }
-
-    protected static void layout(View child, int left, int top) {
-        child.layout(left, top, left + child.getMeasuredWidth(), top + child.getMeasuredHeight());
+    protected void handleStateChanged(QSTile.State state) {
+        mIcon.setIcon(state);
+        setContentDescription(state.contentDescription);
     }
 
     private class H extends Handler {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
index 4cc2b8d..41ac4d9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
@@ -17,26 +17,16 @@
 package com.android.systemui.qs;
 
 import android.content.Context;
-import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.content.res.TypedArray;
 import android.graphics.Typeface;
-import android.graphics.drawable.Animatable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.RippleDrawable;
 import android.util.MathUtils;
 import android.util.TypedValue;
 import android.view.Gravity;
 import android.view.View;
-import android.widget.ImageView;
-import android.widget.ImageView.ScaleType;
 import android.widget.TextView;
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
-import com.android.systemui.qs.QSTile.AnimationIcon;
-
-import java.util.Objects;
 
 /** View that represents a standard quick settings tile. **/
 public class QSTileView extends QSTileBaseView {
@@ -44,59 +34,25 @@
             Typeface.NORMAL);
 
     protected final Context mContext;
-    private final View mIcon;
-    private final View mDivider;
-    private final int mIconSizePx;
     private final int mTileSpacingPx;
     private int mTilePaddingTopPx;
-    private final int mTilePaddingBelowIconPx;
-    private final int mDualTileVerticalPaddingPx;
-    private final View mTopBackgroundView;
 
     private TextView mLabel;
-    private QSDualTileLabel mDualLabel;
-    private int mType;
-    private OnClickListener mClickPrimary;
-    private OnClickListener mClickSecondary;
-    private OnLongClickListener mLongClick;
-    private Drawable mTileBackground;
-    private RippleDrawable mRipple;
 
-    private View mCircle;
-
-    public QSTileView(Context context) {
-        super(context);
+    public QSTileView(Context context, QSIconView icon) {
+        super(context, icon);
 
         mContext = context;
         final Resources res = context.getResources();
-        mIconSizePx = res.getDimensionPixelSize(R.dimen.qs_tile_icon_size);
         mTileSpacingPx = res.getDimensionPixelSize(R.dimen.qs_tile_spacing);
-        mTilePaddingBelowIconPx =  res.getDimensionPixelSize(R.dimen.qs_tile_padding_below_icon);
-        mDualTileVerticalPaddingPx =
-                res.getDimensionPixelSize(R.dimen.qs_dual_tile_padding_vertical);
-        mTileBackground = newTileBackground();
-        recreateLabel();
         setClipChildren(false);
 
-        mTopBackgroundView = new View(context);
-        mTopBackgroundView.setId(View.generateViewId());
-        addView(mTopBackgroundView);
-
-        mIcon = createIcon();
-        addView(mIcon);
-
-        mCircle = createCircleIcon();
-        addView(mCircle);
-
-        mDivider = new View(mContext);
-        mDivider.setBackgroundColor(context.getColor(R.color.qs_tile_divider));
-        final int dh = res.getDimensionPixelSize(R.dimen.qs_tile_divider_height);
-        mDivider.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, dh));
-        addView(mDivider);
-
         setClickable(true);
         updateTopPadding();
         setId(View.generateViewId());
+        createLabel();
+        setOrientation(VERTICAL);
+        setGravity(Gravity.CENTER);
     }
 
     private void updateTopPadding() {
@@ -106,6 +62,8 @@
         float largeFactor = (MathUtils.constrain(getResources().getConfiguration().fontScale,
                 1.0f, FontSizeUtils.LARGE_TEXT_SCALE) - 1f) / (FontSizeUtils.LARGE_TEXT_SCALE - 1f);
         mTilePaddingTopPx = Math.round((1 - largeFactor) * padding + largeFactor * largePadding);
+        setPadding(mTileSpacingPx, mTilePaddingTopPx + mTileSpacingPx, mTileSpacingPx,
+                mTileSpacingPx);
         requestLayout();
     }
 
@@ -114,260 +72,29 @@
         super.onConfigurationChanged(newConfig);
         updateTopPadding();
         FontSizeUtils.updateFontSize(mLabel, R.dimen.qs_tile_text_size);
-        if (mDualLabel != null) {
-            mDualLabel.setTextSize(TypedValue.COMPLEX_UNIT_PX,
-                    getResources().getDimensionPixelSize(R.dimen.qs_tile_text_size));
-        }
     }
 
-    private void recreateLabel() {
-        CharSequence labelText = null;
-        CharSequence labelDescription = null;
-        if (mLabel != null) {
-            labelText = mLabel.getText();
-            removeView(mLabel);
-            mLabel = null;
-        }
-        if (mDualLabel != null) {
-            labelText = mDualLabel.getText();
-            labelDescription = mLabel != null ? mLabel.getContentDescription() : null;
-            removeView(mDualLabel);
-            mDualLabel = null;
-        }
+    private void createLabel() {
         final Resources res = mContext.getResources();
-        if (mType == QS_TYPE_DUAL) {
-            mDualLabel = new QSDualTileLabel(mContext);
-            mDualLabel.setId(View.generateViewId());
-            mDualLabel.setBackgroundResource(R.drawable.btn_borderless_rect);
-            mDualLabel.setFirstLineCaret(mContext.getDrawable(R.drawable.qs_dual_tile_caret));
-            mDualLabel.setTextColor(mContext.getColor(R.color.qs_tile_text));
-            mDualLabel.setPadding(0, mDualTileVerticalPaddingPx, 0, mDualTileVerticalPaddingPx);
-            mDualLabel.setTypeface(CONDENSED);
-            mDualLabel.setTextSize(TypedValue.COMPLEX_UNIT_PX,
-                    res.getDimensionPixelSize(R.dimen.qs_tile_text_size));
-            mDualLabel.setClickable(true);
-            mDualLabel.setOnClickListener(mClickSecondary);
-            mDualLabel.setFocusable(true);
-            if (labelText != null) {
-                mDualLabel.setText(labelText);
-            }
-            if (labelDescription != null) {
-                mDualLabel.setContentDescription(labelDescription);
-            }
-            addView(mDualLabel);
-            mDualLabel.setAccessibilityTraversalAfter(mTopBackgroundView.getId());
-        } else if (mType == QS_TYPE_NORMAL) {
-            mLabel = new TextView(mContext);
-            mLabel.setTextColor(mContext.getColor(R.color.qs_tile_text));
-            mLabel.setGravity(Gravity.CENTER_HORIZONTAL);
-            mLabel.setMinLines(2);
-            mLabel.setPadding(0, 0, 0, 0);
-            mLabel.setTypeface(CONDENSED);
-            mLabel.setTextSize(TypedValue.COMPLEX_UNIT_PX,
-                    res.getDimensionPixelSize(R.dimen.qs_tile_text_size));
-            mLabel.setClickable(false);
-            if (labelText != null) {
-                mLabel.setText(labelText);
-            }
-            addView(mLabel);
-        }
+        mLabel = new TextView(mContext);
+        mLabel.setTextColor(mContext.getColor(R.color.qs_tile_text));
+        mLabel.setGravity(Gravity.CENTER_HORIZONTAL);
+        mLabel.setMinLines(2);
+        mLabel.setPadding(0, 0, 0, 0);
+        mLabel.setTypeface(CONDENSED);
+        mLabel.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+                res.getDimensionPixelSize(R.dimen.qs_tile_text_size));
+        mLabel.setClickable(false);
+        addView(mLabel);
     }
 
-    public boolean setType(int type) {
-        final boolean changed = mType != type;
-        mType = type;
-        if (changed) {
-            recreateLabel();
-        }
-        if (mTileBackground instanceof RippleDrawable) {
-            setRipple((RippleDrawable) mTileBackground);
-        }
-        if (mType == QS_TYPE_DUAL) {
-            mTopBackgroundView.setOnClickListener(mClickPrimary);
-            setOnClickListener(null);
-            setClickable(false);
-            setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
-            mTopBackgroundView.setBackground(mTileBackground);
-        } else {
-            mTopBackgroundView.setOnClickListener(null);
-            mTopBackgroundView.setClickable(false);
-            setOnClickListener(mClickPrimary);
-            setOnLongClickListener(mLongClick);
-            setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
-            setBackground(mTileBackground);
-        }
-        mTopBackgroundView.setFocusable(mType == QS_TYPE_DUAL);
-        setFocusable(mType != QS_TYPE_DUAL);
-        mDivider.setVisibility(mType == QS_TYPE_DUAL ? VISIBLE : GONE);
-        mCircle.setVisibility(mType == QS_TYPE_QUICK ? VISIBLE : GONE);
-        postInvalidate();
-        return changed;
-    }
-
-    private void setRipple(RippleDrawable tileBackground) {
-        mRipple = tileBackground;
-        if (getWidth() != 0) {
-            updateRippleSize(getWidth(), getHeight());
-        }
-    }
-
-    public void init(OnClickListener clickPrimary, OnClickListener clickSecondary,
-            OnLongClickListener longClick) {
-        mClickPrimary = clickPrimary;
-        mClickSecondary = clickSecondary;
-        mLongClick = longClick;
-    }
-
-    protected View createIcon() {
-        final ImageView icon = new ImageView(mContext);
-        icon.setId(android.R.id.icon);
-        icon.setScaleType(ScaleType.CENTER_INSIDE);
-        return icon;
-    }
-
-    protected View createCircleIcon() {
-        final ImageView icon = new ImageView(mContext);
-        icon.setImageResource(R.drawable.ic_qs_circle);
-        // TODO: Not this.
-        icon.setPadding(20, 20, 20, 20);
-        return icon;
-    }
-
-    protected View createCircle() {
-        final ImageView icon = new ImageView(mContext);
-        icon.setId(android.R.id.icon);
-        icon.setScaleType(ScaleType.CENTER_INSIDE);
-        return icon;
-    }
-
-    private Drawable newTileBackground() {
-        final int[] attrs = new int[] { android.R.attr.selectableItemBackgroundBorderless };
-        final TypedArray ta = mContext.obtainStyledAttributes(attrs);
-        final Drawable d = ta.getDrawable(0);
-        ta.recycle();
-        return d;
-    }
-
-    private View labelView() {
-        return mType == QS_TYPE_DUAL ? mDualLabel : mLabel;
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        final int w = MeasureSpec.getSize(widthMeasureSpec);
-        final int h = MeasureSpec.getSize(heightMeasureSpec);
-        final int iconSpec = exactly(mIconSizePx);
-        mIcon.measure(MeasureSpec.makeMeasureSpec(w, getIconMeasureMode()), iconSpec);
-        switch (mType) {
-            case QS_TYPE_QUICK:
-                mCircle.measure(
-                        MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY),
-                        MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY));
-                break;
-            case QS_TYPE_DUAL:
-                mDivider.measure(widthMeasureSpec, exactly(mDivider.getLayoutParams().height));
-            default:
-                labelView().measure(widthMeasureSpec,
-                        MeasureSpec.makeMeasureSpec(h, MeasureSpec.AT_MOST));
-                break;
-        }
-        int heightSpec = exactly(
-                mIconSizePx + mTilePaddingBelowIconPx + mTilePaddingTopPx);
-        mTopBackgroundView.measure(widthMeasureSpec, heightSpec);
-        setMeasuredDimension(w, h);
-    }
-
-    protected int getIconMeasureMode() {
-        return MeasureSpec.EXACTLY;
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        final int w = getMeasuredWidth();
-        final int h = getMeasuredHeight();
-
-        layout(mTopBackgroundView, 0, mTileSpacingPx);
-
-        int top = 0;
-        top += mTileSpacingPx;
-        top += mTilePaddingTopPx;
-        final int iconLeft = (w - mIcon.getMeasuredWidth()) / 2;
-        if (mType == QS_TYPE_QUICK) {
-            top = (h - mIcon.getMeasuredHeight()) / 2;
-            layout(mCircle, 0, 0);
-        }
-        layout(mIcon, iconLeft, top);
-        if (mRipple != null) {
-            updateRippleSize(w, h);
-
-        }
-        top = mIcon.getBottom();
-        top += mTilePaddingBelowIconPx;
-        if (mType == QS_TYPE_DUAL) {
-            layout(mDivider, 0, top);
-            top = mDivider.getBottom();
-        }
-        if (mType != QS_TYPE_QUICK) {
-            layout(labelView(), 0, top);
-        }
-    }
-
-    private void updateRippleSize(int width, int height) {
-        // center the touch feedback on the center of the icon, and dial it down a bit
-        final int cx = width / 2;
-        final int cy = mType == QS_TYPE_DUAL ? mIcon.getTop() + mIcon.getHeight() / 2 : height / 2;
-        final int rad = (int)(mIcon.getHeight() * 1.25f);
-        mRipple.setHotspotBounds(cx - rad, cy - rad, cx + rad, cy + rad);
+    public void init(OnClickListener clickPrimary, OnLongClickListener longClick) {
+        setOnClickListener(clickPrimary);
+        setOnLongClickListener(longClick);
     }
 
     protected void handleStateChanged(QSTile.State state) {
-        if (mIcon instanceof ImageView) {
-            setIcon((ImageView) mIcon, state);
-        }
-        if (mType == QS_TYPE_DUAL) {
-            mDualLabel.setText(state.label);
-            mDualLabel.setContentDescription(state.dualLabelContentDescription);
-            mTopBackgroundView.setContentDescription(state.contentDescription);
-        } else if (mType == QS_TYPE_NORMAL) {
-            mLabel.setText(state.label);
-            setContentDescription(state.contentDescription);
-        }
-    }
-
-    protected void setIcon(ImageView iv, QSTile.State state) {
-        if (!Objects.equals(state.icon, iv.getTag(R.id.qs_icon_tag))) {
-            Drawable d = state.icon != null ? state.icon.getDrawable(mContext) : null;
-            if (d != null && state.autoMirrorDrawable) {
-                d.setAutoMirrored(true);
-            }
-            iv.setImageDrawable(d);
-            iv.setTag(R.id.qs_icon_tag, state.icon);
-            if (d instanceof Animatable) {
-                Animatable a = (Animatable) d;
-                if (state.icon instanceof AnimationIcon && !iv.isShown()) {
-                    a.stop(); // skip directly to end state
-                }
-            }
-        }
-    }
-
-    /**
-     * Update the accessibility order for this view.
-     *
-     * @param previousView the view which should be before this one
-     * @return the last view in this view which is accessible
-     */
-    public View updateAccessibilityOrder(View previousView) {
-        View firstView;
-        View lastView;
-        if (mType == QS_TYPE_DUAL) {
-            lastView = mDualLabel;
-            firstView = mTopBackgroundView;
-        } else {
-            firstView = this;
-            lastView = this;
-        }
-        firstView.setAccessibilityTraversalAfter(previousView.getId());
-        return lastView;
+        super.handleStateChanged(state);
+        mLabel.setText(state.label);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 6a053be..bda4675 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.Gravity;
 import android.view.View;
 import android.widget.ImageView;
@@ -30,10 +29,14 @@
 import java.util.Collection;
 
 /**
- * Version of QSPanel that only shows 4 Quick Tiles in the QS Header.
+ * Version of QSPanel that only shows N Quick Tiles in the QS Header.
  */
 public class QuickQSPanel extends QSPanel {
 
+    private int mMaxTiles;
+    private QSPanel mFullPanel;
+    private View mHeader;
+
     public QuickQSPanel(Context context, AttributeSet attrs) {
         super(context, attrs);
         if (mTileLayout != null) {
@@ -46,6 +49,36 @@
         mQsContainer.addView((View) mTileLayout, 1 /* Between brightness and footer */);
     }
 
+    public void setQSPanelAndHeader(QSPanel fullPanel, View header) {
+        mFullPanel = fullPanel;
+        mHeader = header;
+    }
+
+    @Override
+    protected void handleShowDetail(QSPanel.Record r, boolean show) {
+        if (show) {
+            mHeader.performClick();
+            mFullPanel.showDetail(show, r);
+        } else {
+            // Not sure how we would end up here...
+            super.handleShowDetail(r, show);
+        }
+    }
+
+    @Override
+    protected QSTileBaseView createTileView(QSTile<?> tile) {
+        return new QSTileBaseView(mContext, tile.createTileView(mContext));
+    }
+
+    public void setMaxTiles(int maxTiles) {
+        mMaxTiles = maxTiles;
+    }
+
+    @Override
+    protected void onTileClick(QSTile<?> tile) {
+        tile.secondaryClick();
+    }
+
     @Override
     public void onTuningChanged(String key, String newValue) {
         // No tunings for you.
@@ -59,11 +92,8 @@
     public void setTiles(Collection<QSTile<?>> tiles) {
         ArrayList<QSTile<?>> quickTiles = new ArrayList<>();
         for (QSTile<?> tile : tiles) {
-            if (tile.getTileType() == QSTileView.QS_TYPE_QUICK) {
-                Log.d("QSPanel", "Adding " + tile.getTileSpec());
-                quickTiles.add(tile);
-            }
-            if (quickTiles.size() == 2) {
+            quickTiles.add(tile);
+            if (quickTiles.size() == mMaxTiles) {
                 break;
             }
         }
@@ -74,6 +104,8 @@
 
         public HeaderTileLayout(Context context) {
             super(context);
+            setClipChildren(false);
+            setClipToPadding(false);
             setGravity(Gravity.CENTER_VERTICAL);
             setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
 
@@ -92,17 +124,14 @@
         @Override
         public void addTile(TileRecord tile) {
             tile.tileView.setLayoutParams(generateLayoutParams());
-            // These shouldn't be normal tiles, but they will be for now so that the circles don't
-            // show up.
-            tile.tileView.setType(QSTileView.QS_TYPE_NORMAL);
             addView(tile.tileView, getChildCount() - 1 /* Leave icon at end */);
         }
 
         private LayoutParams generateLayoutParams() {
-            int size =
-                    mContext.getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_size);
+            int size = mContext.getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_size);
             LayoutParams lp = new LayoutParams(0, size);
             lp.weight = 1;
+            lp.gravity = Gravity.CENTER;
             return lp;
         }
 
@@ -112,11 +141,6 @@
         }
 
         @Override
-        public void setTileVisibility(TileRecord tile, int visibility) {
-            tile.tileView.setVisibility(visibility);
-        }
-
-        @Override
         public int getOffsetTop(TileRecord tile) {
             return 0;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
index a2e1296..b2bfa06 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
@@ -27,7 +27,7 @@
 import com.android.systemui.qs.QSTile.SignalState;
 
 /** View that represents a custom quick settings tile for displaying signal info (wifi/cell). **/
-public final class SignalTileView extends QSTileView {
+public final class SignalTileView extends QSIconView {
     private static final long DEFAULT_DURATION = new ValueAnimator().getDuration();
     private static final long SHORT_DURATION = DEFAULT_DURATION / 3;
 
@@ -106,8 +106,7 @@
     }
 
     @Override
-    protected void handleStateChanged(QSTile.State state) {
-        super.handleStateChanged(state);
+    public void setIcon(QSTile.State state) {
         final SignalState s = (SignalState) state;
         setIcon(mSignal, s);
         if (s.overlayIconId > 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index 1336eec..ff11177 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -18,14 +18,9 @@
 
     private static final String TAG = "TileLayout";
 
-    private int mDualTileUnderlap;
     protected int mColumns;
     private int mCellWidth;
     private int mCellHeight;
-    private int mLargeCellWidth;
-    private int mLargeCellHeight;
-
-    protected boolean mAllowDual = true;
 
     protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
 
@@ -59,21 +54,11 @@
         super.removeAllViews();
     }
 
-    @Override
-    public void setTileVisibility(TileRecord tile, int visibility) {
-        tile.tileView.setVisibility(visibility);
-    }
-
     public void updateResources() {
         final Resources res = mContext.getResources();
         final int columns = Math.max(1, res.getInteger(R.integer.quick_settings_num_columns));
         mCellHeight = getCellHeight();
         mCellWidth = (int) (mCellHeight * TILE_ASPECT);
-        mLargeCellHeight = mAllowDual ? res.getDimensionPixelSize(R.dimen.qs_dual_tile_height)
-                : mCellHeight;
-        mLargeCellWidth = mAllowDual ? (int) (mLargeCellHeight * TILE_ASPECT) : mCellWidth;
-        mDualTileUnderlap = mAllowDual
-                ? res.getDimensionPixelSize(R.dimen.qs_dual_tile_padding_vertical) : 0;
         if (mColumns != columns) {
             mColumns = columns;
             postInvalidate();
@@ -90,16 +75,13 @@
         int r = -1;
         int c = -1;
         int rows = 0;
-        boolean rowIsDual = false;
         for (TileRecord record : mRecords) {
             if (record.tileView.getVisibility() == GONE) continue;
             // wrap to next column if we've reached the max # of columns
             // also don't allow dual + single tiles on the same row
-            if (r == -1 || c == (mColumns - 1)
-                    || rowIsDual != (mAllowDual && record.tile.supportsDualTargets())) {
+            if (r == -1 || c == (mColumns - 1)) {
                 r++;
                 c = 0;
-                rowIsDual = mAllowDual && record.tile.supportsDualTargets();
             } else {
                 c++;
             }
@@ -110,13 +92,9 @@
 
         View previousView = this;
         for (TileRecord record : mRecords) {
-            if (record.tileView.setType(mAllowDual ? record.tile.getTileType()
-                    : QSTileView.QS_TYPE_NORMAL)) {
-                record.tileView.handleStateChanged(record.tile.getState());
-            }
             if (record.tileView.getVisibility() == GONE) continue;
-            final int cw = record.row == 0 ? mLargeCellWidth : mCellWidth;
-            final int ch = record.row == 0 ? mLargeCellHeight : mCellHeight;
+            final int cw = mCellWidth;
+            final int ch = mCellHeight;
             record.tileView.measure(exactly(cw), exactly(ch));
             previousView = record.tileView.updateAccessibilityOrder(previousView);
         }
@@ -135,7 +113,7 @@
         for (TileRecord record : mRecords) {
             if (record.tileView.getVisibility() == GONE) continue;
             final int cols = getColumnCount(record.row);
-            final int cw = record.row == 0 ? mLargeCellWidth : mCellWidth;
+            final int cw = mCellWidth;
             final int extra = (w - cw * cols) / (cols + 1);
             int left = record.col * cw + (record.col + 1) * extra;
             final int top = getRowTop(record.row);
@@ -153,7 +131,7 @@
 
     private int getRowTop(int row) {
         if (row <= 0) return 0;
-        return mLargeCellHeight - mDualTileUnderlap + (row - 1) * mCellHeight;
+        return row * mCellHeight;
     }
 
     private int getColumnCount(int row) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/UsageTracker.java b/packages/SystemUI/src/com/android/systemui/qs/UsageTracker.java
deleted file mode 100644
index e64f6a0..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/UsageTracker.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.qs;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-
-import com.android.systemui.Prefs;
-import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.SystemUIDialog;
-import com.android.systemui.statusbar.policy.Listenable;
-
-public class UsageTracker implements Listenable {
-    private static final long MILLIS_PER_DAY = 1000 * 60 * 60 * 24;
-
-    private final Context mContext;
-    private final long mTimeToShowTile;
-    @Prefs.Key private final String mPrefKey;
-    private final String mResetAction;
-
-    private boolean mRegistered;
-
-    public UsageTracker(Context context, @Prefs.Key String prefKey, Class<?> tile,
-            int timeoutResource) {
-        mContext = context;
-        mPrefKey = prefKey;
-        mTimeToShowTile = MILLIS_PER_DAY * mContext.getResources().getInteger(timeoutResource);
-        mResetAction = "com.android.systemui.qs." + tile.getSimpleName() + ".usage_reset";
-    }
-
-    @Override
-    public void setListening(boolean listen) {
-        if (listen && !mRegistered) {
-             mContext.registerReceiver(mReceiver, new IntentFilter(mResetAction));
-             mRegistered = true;
-        } else if (!listen && mRegistered) {
-            mContext.unregisterReceiver(mReceiver);
-            mRegistered = false;
-        }
-    }
-
-    public boolean isRecentlyUsed() {
-        long lastUsed = Prefs.getLong(mContext, mPrefKey, 0L /* defaultValue */);
-        return (System.currentTimeMillis() - lastUsed) < mTimeToShowTile;
-    }
-
-    public void trackUsage() {
-        Prefs.putLong(mContext, mPrefKey, System.currentTimeMillis());
-    }
-
-    public void reset() {
-        Prefs.remove(mContext, mPrefKey);
-    }
-
-    public void showResetConfirmation(String title, final Runnable onConfirmed) {
-        final SystemUIDialog d = new SystemUIDialog(mContext);
-        d.setTitle(title);
-        d.setMessage(mContext.getString(R.string.quick_settings_reset_confirmation_message));
-        d.setNegativeButton(android.R.string.cancel, null);
-        d.setPositiveButton(R.string.quick_settings_reset_confirmation_button,
-                new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-                reset();
-                if (onConfirmed != null) {
-                    onConfirmed.run();
-                }
-            }
-        });
-        d.setCanceledOnTouchOutside(true);
-        d.show();
-    }
-
-    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (mResetAction.equals(intent.getAction())) {
-                reset();
-            }
-        }
-    };
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/BlankCustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/customize/BlankCustomTile.java
index a4ff685..95ff611 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/BlankCustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/BlankCustomTile.java
@@ -72,12 +72,10 @@
         try {
             PackageManager pm = mContext.getPackageManager();
             ServiceInfo info = pm.getServiceInfo(mComponent, 0);
-            state.visible = true;
             state.icon = new DrawableIcon(info.loadIcon(pm));
             state.label = info.loadLabel(pm).toString();
             state.contentDescription = state.label;
         } catch (Exception e) {
-            state.visible = false;
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/CustomQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/customize/CustomQSPanel.java
index 422ae4d..87c2973 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/CustomQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/CustomQSPanel.java
@@ -81,6 +81,11 @@
         }
     }
 
+    @Override
+    protected void createCustomizePanel() {
+        // Already in CustomizePanel.
+    }
+
     public void tileSelected(QSTile<?> tile, ClipData currentClip) {
         String sourceSpec = getSpec(currentClip);
         String destSpec = tile.getTileSpec();
@@ -176,13 +181,16 @@
             if (mTiles.get(i).startsWith(CustomTile.PREFIX)) {
                 mCurrentTiles.add(BlankCustomTile.create(mHost, mTiles.get(i)));
             } else {
-                mCurrentTiles.add(mHost.createTile(mTiles.get(i)));
+                QSTile<?> tile = mHost.createTile(mTiles.get(i));
+                if (tile != null) {
+                    mCurrentTiles.add(tile);
+                }
             }
             mCurrentTiles.get(mCurrentTiles.size() - 1).setTileSpec(mTiles.get(i));
         }
         super.setTiles(mCurrentTiles);
     }
-    
+
     public void addTile(String spec) {
         mTiles.add(spec);
         setTilesInternal();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/NonPagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/customize/NonPagedTileLayout.java
index d0d5b54..3acbed8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/NonPagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/NonPagedTileLayout.java
@@ -25,14 +25,12 @@
 import android.view.View;
 import android.view.View.OnTouchListener;
 import android.widget.LinearLayout;
-
 import com.android.systemui.R;
 import com.android.systemui.qs.PagedTileLayout;
 import com.android.systemui.qs.PagedTileLayout.TilePage;
 import com.android.systemui.qs.QSPanel.QSTileLayout;
 import com.android.systemui.qs.QSPanel.TileRecord;
 import com.android.systemui.qs.QSTile;
-import com.android.systemui.qs.QSTileView;
 import com.android.systemui.qs.QuickTileLayout;
 
 import java.util.ArrayList;
@@ -75,13 +73,12 @@
     public void addTile(TileRecord record) {
         mTiles.add(record);
         distributeTiles();
-        if (record.tile.getTileType() == QSTileView.QS_TYPE_QUICK
-                || record.tileView.getTag() == record.tile) {
+        if (record.tileView.getTag() == record.tile) {
             return;
         }
         record.tileView.setTag(record.tile);
         record.tileView.setVisibility(View.VISIBLE);
-        record.tileView.init(null, null, null);
+        record.tileView.init(null, null);
         record.tileView.setOnTouchListener(this);
         if (mCurrentClip != null && mCurrentClip.getItemAt(0)
                 .getText().toString().equals(record.tile.getTileSpec())) {
@@ -107,10 +104,6 @@
         final int NT = mTiles.size();
         for (int i = 0; i < NT; i++) {
             TileRecord tile = mTiles.get(i);
-            if (tile.tile.getTileType() == QSTileView.QS_TYPE_QUICK) {
-                // Ignore quick tiles for now.
-                continue;
-            }
             mPages.get(index).addTile(tile);
             // Keep everything in one layout for now.
             if (false && mPages.get(index).isFull()) {
@@ -125,12 +118,6 @@
     }
 
     @Override
-    public void setTileVisibility(TileRecord tile, int visibility) {
-        // All tiles visible here, so that they can be re-arranged.
-        tile.tileView.setVisibility(View.VISIBLE);
-    }
-
-    @Override
     public int getOffsetTop(TileRecord tile) {
         // No touch feedback, so this isn't required.
         return 0;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index baad370..4a7d67f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -37,9 +37,7 @@
 import android.widget.ListView;
 import android.widget.Toolbar;
 import android.widget.Toolbar.OnMenuItemClickListener;
-
 import com.android.systemui.R;
-import com.android.systemui.SystemUIApplication;
 import com.android.systemui.qs.QSDetailClipper;
 import com.android.systemui.qs.QSTile.Host.Callback;
 import com.android.systemui.qs.customize.DropButton.OnDropListener;
@@ -80,14 +78,13 @@
 
     public QSCustomizer(Context context, AttributeSet attrs) {
         super(new ContextThemeWrapper(context, android.R.style.Theme_Material), attrs);
-        mPhoneStatusBar = ((SystemUIApplication) mContext.getApplicationContext())
-                .getComponent(PhoneStatusBar.class);
         mClipper = new QSDetailClipper(this);
     }
 
     public void setHost(QSTileHost host) {
         mHost = host;
         mHost.addCallback(this);
+        mPhoneStatusBar = host.getPhoneStatusBar();
         mQsPanel.setTiles(mHost.getTiles());
         mQsPanel.setHost(mHost);
         mQsPanel.setSavedTiles();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index 144b202..6706c7a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -88,6 +88,9 @@
                 }
                 Log.d(TAG, "Trying " + spec);
                 final QSTile<?> tile = host.createTile(spec);
+                if (tile == null) {
+                    continue;
+                }
                 // Bad, bad, very bad.
                 tile.setListening(true);
                 tile.clearState();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index 49f8d1c..fc802dd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -73,7 +73,6 @@
         final int value = arg instanceof Integer ? (Integer)arg : mSetting.getValue();
         final boolean airplaneMode = value != 0;
         state.value = airplaneMode;
-        state.visible = true;
         state.label = mContext.getString(R.string.airplane_mode);
         if (airplaneMode) {
             state.icon = mEnable;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
index 8f9655d..84eac65 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
@@ -73,7 +73,6 @@
         int level = (arg != null) ? (Integer) arg : mLevel;
         String percentage = NumberFormat.getPercentInstance().format((double) level / 100.0);
 
-        state.visible = true;
         state.icon = new Icon() {
             @Override
             public Drawable getDrawable(Context context) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 7f07ddc..cfc09a0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -24,18 +24,15 @@
 import android.text.TextUtils;
 import android.view.View;
 import android.view.ViewGroup;
-
 import com.android.internal.logging.MetricsLogger;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSDetailItems;
 import com.android.systemui.qs.QSDetailItems.Item;
 import com.android.systemui.qs.QSTile;
-import com.android.systemui.qs.QSTileView;
 import com.android.systemui.statusbar.policy.BluetoothController;
 
 import java.util.Collection;
-import java.util.Set;
 
 /** Quick settings tile: Bluetooth **/
 public class BluetoothTile extends QSTile<QSTile.BooleanState>  {
@@ -44,21 +41,13 @@
     private final BluetoothController mController;
     private final BluetoothDetailAdapter mDetailAdapter;
 
-    private final boolean mAlwaysDetail;
-
-    public BluetoothTile(Host host, boolean alwaysDetail) {
+    public BluetoothTile(Host host) {
         super(host);
-        mAlwaysDetail = alwaysDetail;
         mController = host.getBluetoothController();
         mDetailAdapter = new BluetoothDetailAdapter();
     }
 
     @Override
-    public int getTileType() {
-        return QSTileView.QS_TYPE_DUAL;
-    }
-
-    @Override
     public DetailAdapter getDetailAdapter() {
         return mDetailAdapter;
     }
@@ -78,18 +67,15 @@
     }
 
     @Override
-    protected void handleClick() {
-        if (mAlwaysDetail) {
-            handleSecondaryClick();
-            return;
-        }
+    protected void handleSecondaryClick() {
+        // Secondary clicks are header clicks, just toggle.
         final boolean isEnabled = (Boolean)mState.value;
         MetricsLogger.action(mContext, getMetricsCategory(), !isEnabled);
         mController.setBluetoothEnabled(!isEnabled);
     }
 
     @Override
-    protected void handleSecondaryClick() {
+    protected void handleClick() {
         if (!mState.value) {
             mState.value = true;
             mController.setBluetoothEnabled(true);
@@ -99,11 +85,9 @@
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
-        final boolean supported = mController.isBluetoothSupported();
         final boolean enabled = mController.isBluetoothEnabled();
         final boolean connected = mController.isBluetoothConnected();
         final boolean connecting = mController.isBluetoothConnecting();
-        state.visible = supported;
         state.value = enabled;
         state.autoMirrorDrawable = false;
         if (enabled) {
@@ -155,6 +139,10 @@
         }
     }
 
+    public static boolean isSupported(Host host) {
+        return host.getBluetoothController().isBluetoothSupported();
+    }
+
     private final BluetoothController.Callback mCallback = new BluetoothController.Callback() {
         @Override
         public void onBluetoothStateChange(boolean enabled) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 48b74a4..a8e139c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -23,12 +23,10 @@
 import android.view.View;
 import android.view.View.OnAttachStateChangeListener;
 import android.view.ViewGroup;
-
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSDetailItems;
 import com.android.systemui.qs.QSDetailItems.Item;
-import com.android.systemui.qs.QSPanel;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.statusbar.policy.CastController;
 import com.android.systemui.statusbar.policy.CastController.CastDevice;
@@ -87,14 +85,23 @@
 
     @Override
     protected void handleClick() {
+        if (mKeyguard.isSecure() && !mKeyguard.canSkipBouncer()) {
+            mHost.startRunnableDismissingKeyguard(new Runnable() {
+                @Override
+                public void run() {
+                    MetricsLogger.action(mContext, getMetricsCategory());
+                    showDetail(true);
+                    mHost.openPanels();
+                }
+            });
+            return;
+        }
         MetricsLogger.action(mContext, getMetricsCategory());
         showDetail(true);
     }
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
-        state.visible = !mKeyguard.isSecure() || !mKeyguard.isShowing()
-                || mKeyguard.canSkipBouncer() || QSPanel.isTheNewQS(mContext);
         state.label = mContext.getString(R.string.quick_settings_cast_title);
         state.value = false;
         state.autoMirrorDrawable = false;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index a0bbbe3..6c7b337 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -26,8 +26,8 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.settingslib.net.MobileDataController;
 import com.android.systemui.R;
+import com.android.systemui.qs.QSIconView;
 import com.android.systemui.qs.QSTile;
-import com.android.systemui.qs.QSTileBaseView;
 import com.android.systemui.qs.SignalTileView;
 import com.android.systemui.statusbar.policy.NetworkController;
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
@@ -71,7 +71,7 @@
     }
 
     @Override
-    public QSTileBaseView createTileView(Context context) {
+    public QSIconView createTileView(Context context) {
         return new SignalTileView(context);
     }
 
@@ -86,9 +86,15 @@
     }
 
     @Override
+    protected void handleSecondaryClick() {
+        boolean dataEnabled = mDataController.isMobileDataSupported()
+                && mDataController.isMobileDataEnabled();
+        MetricsLogger.action(mContext, MetricsLogger.QS_CELLULAR_TOGGLE, !dataEnabled);
+        mDataController.setMobileDataEnabled(!dataEnabled);
+    }
+
+    @Override
     protected void handleUpdateState(SignalState state, Object arg) {
-        state.visible = mController.hasMobileDataFeature();
-        if (!state.visible) return;
         CallbackInfo cb = (CallbackInfo) arg;
         if (cb == null) {
             cb = mSignalCallback.mInfo;
@@ -138,6 +144,10 @@
         return string;
     }
 
+    public static boolean isSupported(Host host) {
+        return host.getNetworkController().hasMobileDataFeature();
+    }
+
     private static final class CallbackInfo {
         boolean enabled;
         boolean wifiEnabled;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index 2f9a496..f73ee35 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -17,14 +17,10 @@
 package com.android.systemui.qs.tiles;
 
 import android.provider.Settings.Secure;
-
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.Prefs;
 import com.android.systemui.R;
-import com.android.systemui.qs.QSPanel;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.qs.SecureSetting;
-import com.android.systemui.qs.UsageTracker;
 
 /** Quick settings tile: Invert colors **/
 public class ColorInversionTile extends QSTile<QSTile.BooleanState> {
@@ -34,7 +30,6 @@
     private final AnimationIcon mDisable
             = new AnimationIcon(R.drawable.ic_invert_colors_disable_animation);
     private final SecureSetting mSetting;
-    private final UsageTracker mUsageTracker;
 
     private boolean mListening;
 
@@ -45,28 +40,14 @@
                 Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED) {
             @Override
             protected void handleValueChanged(int value, boolean observedChange) {
-                if (value != 0 || observedChange) {
-                    mUsageTracker.trackUsage();
-                }
-                if (mListening) {
-                    handleRefreshState(value);
-                }
+                handleRefreshState(value);
             }
         };
-        mUsageTracker = new UsageTracker(host.getContext(),
-                Prefs.Key.COLOR_INVERSION_TILE_LAST_USED, ColorInversionTile.class,
-                R.integer.days_to_show_color_inversion_tile);
-        if (mSetting.getValue() != 0 && !mUsageTracker.isRecentlyUsed()) {
-            mUsageTracker.trackUsage();
-        }
-        mUsageTracker.setListening(true);
-        mSetting.setListening(true);
     }
 
     @Override
     protected void handleDestroy() {
         super.handleDestroy();
-        mUsageTracker.setListening(false);
         mSetting.setListening(false);
     }
 
@@ -77,7 +58,7 @@
 
     @Override
     public void setListening(boolean listening) {
-        mListening = listening;
+        mSetting.setListening(listening);
     }
 
     @Override
@@ -95,23 +76,9 @@
     }
 
     @Override
-    protected void handleLongClick() {
-        if (mState.value) return;  // don't allow usage reset if inversion is active
-        final String title = mContext.getString(R.string.quick_settings_reset_confirmation_title,
-                mState.label);
-        mUsageTracker.showResetConfirmation(title, new Runnable() {
-            @Override
-            public void run() {
-                refreshState();
-            }
-        });
-    }
-
-    @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
         final int value = arg instanceof Integer ? (Integer) arg : mSetting.getValue();
         final boolean enabled = value != 0;
-        state.visible = enabled || mUsageTracker.isRecentlyUsed() || QSPanel.isTheNewQS(mContext);
         state.value = enabled;
         state.label = mContext.getString(R.string.quick_settings_inversion_label);
         state.icon = enabled ? mEnable : mDisable;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CustomTile.java
index 04006eb..bb74f34 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CustomTile.java
@@ -104,9 +104,15 @@
                         mServiceConnection, Service.BIND_AUTO_CREATE,
                         new UserHandle(ActivityManager.getCurrentUser()));
                 mBound = true;
+            } else {
+                if (mService != null) {
+                    mService.onStartListening();
+                } else {
+                    Log.d(TAG, "Can't start service listening");
+                }
             }
         } else {
-            if (mService!= null) {
+            if (mService != null) {
                 mService.onStopListening();
             }
             if (mIsTokenGranted && !mIsShowingDialog) {
@@ -168,7 +174,6 @@
 
     @Override
     protected void handleUpdateState(State state, Object arg) {
-        state.visible = true;
         Drawable drawable = mTile.getIcon().loadDrawable(mContext);
         drawable.setTint(mContext.getColor(android.R.color.white));
         state.icon = new DrawableIcon(drawable);
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 781ab1c..d96f735 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -29,7 +29,6 @@
 import android.view.View.OnAttachStateChangeListener;
 import android.view.ViewGroup;
 import android.widget.Toast;
-
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
@@ -126,7 +125,6 @@
         final boolean newValue = zen != Global.ZEN_MODE_OFF;
         final boolean valueChanged = state.value != newValue;
         state.value = newValue;
-        state.visible = isVisible(mContext);
         switch (zen) {
             case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
                 state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_on);
@@ -215,6 +213,10 @@
         }
     };
 
+    public static boolean isSupported(Host host) {
+        return isVisible(host.getContext());
+    }
+
     private final class DndDetailAdapter implements DetailAdapter, OnAttachStateChangeListener {
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index 21cbef2..12c1298 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -17,7 +17,6 @@
 package com.android.systemui.qs.tiles;
 
 import android.app.ActivityManager;
-
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
@@ -71,7 +70,8 @@
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
-        state.visible = mFlashlightController.isAvailable();
+        // TODO: Flashlight available handling...
+//        state.visible = mFlashlightController.isAvailable();
         state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label);
         if (arg instanceof UserBoolean) {
             boolean value = ((UserBoolean) arg).value;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index 79084ae..250d567 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -16,16 +16,9 @@
 
 package com.android.systemui.qs.tiles;
 
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.Prefs;
 import com.android.systemui.R;
-import com.android.systemui.qs.QSPanel;
 import com.android.systemui.qs.QSTile;
-import com.android.systemui.qs.UsageTracker;
 import com.android.systemui.statusbar.policy.HotspotController;
 
 /** Quick settings tile: Hotspot **/
@@ -36,19 +29,15 @@
             new AnimationIcon(R.drawable.ic_hotspot_disable_animation);
     private final HotspotController mController;
     private final Callback mCallback = new Callback();
-    private final UsageTracker mUsageTracker;
 
     public HotspotTile(Host host) {
         super(host);
         mController = host.getHotspotController();
-        mUsageTracker = newUsageTracker(host.getContext());
-        mUsageTracker.setListening(true);
     }
 
     @Override
     protected void handleDestroy() {
         super.handleDestroy();
-        mUsageTracker.setListening(false);
     }
 
     @Override
@@ -75,22 +64,7 @@
     }
 
     @Override
-    protected void handleLongClick() {
-        if (mState.value) return;  // don't allow usage reset if hotspot is active
-        final String title = mContext.getString(R.string.quick_settings_reset_confirmation_title,
-                mState.label);
-        mUsageTracker.showResetConfirmation(title, new Runnable() {
-            @Override
-            public void run() {
-                refreshState();
-            }
-        });
-    }
-
-    @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
-        state.visible = (mController.isHotspotSupported() && mUsageTracker.isRecentlyUsed())
-                || QSPanel.isTheNewQS(mContext);
         state.label = mContext.getString(R.string.quick_settings_hotspot_label);
 
         if (arg instanceof Boolean) {
@@ -98,7 +72,7 @@
         } else {
             state.value = mController.isHotspotEnabled();
         }
-        state.icon = state.visible && state.value ? mEnable : mDisable;
+        state.icon = state.value ? mEnable : mDisable;
     }
 
     @Override
@@ -115,31 +89,10 @@
         }
     }
 
-    private static UsageTracker newUsageTracker(Context context) {
-        return new UsageTracker(context, Prefs.Key.HOTSPOT_TILE_LAST_USED, HotspotTile.class,
-                R.integer.days_to_show_hotspot_tile);
-    }
-
     private final class Callback implements HotspotController.Callback {
         @Override
         public void onHotspotChanged(boolean enabled) {
             refreshState(enabled);
         }
     };
-
-    /**
-     * This will catch broadcasts for changes in hotspot state so we can show
-     * the hotspot tile for a number of days after use.
-     */
-    public static class APChangedReceiver extends BroadcastReceiver {
-        private UsageTracker mUsageTracker;
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (mUsageTracker == null) {
-                mUsageTracker = newUsageTracker(context);
-            }
-            mUsageTracker.trackUsage();
-        }
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
index c7f2284..0883445 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
@@ -124,7 +124,6 @@
         }
         // Save the last one in case we need it later.
         mLastIntent = intent;
-        state.visible = intent.getBooleanExtra("visible", true);
         state.contentDescription = intent.getStringExtra("contentDescription");
         state.label = intent.getStringExtra("label");
         state.icon = null;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index 0e2672c..08540f6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -18,7 +18,6 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.R;
-import com.android.systemui.qs.QSPanel;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 import com.android.systemui.statusbar.policy.LocationController;
@@ -60,6 +59,20 @@
 
     @Override
     protected void handleClick() {
+        if (mKeyguard.isSecure() && mKeyguard.isShowing()) {
+            mHost.startRunnableDismissingKeyguard(new Runnable() {
+                @Override
+                public void run() {
+                    final boolean wasEnabled = (Boolean) mState.value;
+                    mHost.openPanels();
+                    MetricsLogger.action(mContext, getMetricsCategory(), !wasEnabled);
+                    mController.setLocationEnabled(!wasEnabled);
+                    mEnable.setAllowAnimation(true);
+                    mDisable.setAllowAnimation(true);
+                }
+            });
+            return;
+        }
         final boolean wasEnabled = (Boolean) mState.value;
         MetricsLogger.action(mContext, getMetricsCategory(), !wasEnabled);
         mController.setLocationEnabled(!wasEnabled);
@@ -74,7 +87,6 @@
         // Work around for bug 15916487: don't show location tile on top of lock screen. After the
         // bug is fixed, this should be reverted to only hiding it on secure lock screens:
         // state.visible = !(mKeyguard.isSecure() && mKeyguard.isShowing());
-        state.visible = !mKeyguard.isShowing() || QSPanel.isTheNewQS(mContext);
         state.value = locationEnabled;
         if (locationEnabled) {
             state.icon = mEnable;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QAirplaneTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QAirplaneTile.java
deleted file mode 100644
index b77191e..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QAirplaneTile.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.qs.tiles;
-
-import android.content.Context;
-import com.android.systemui.QSQuickTileView;
-import com.android.systemui.qs.QSTileBaseView;
-import com.android.systemui.qs.QSTileView;
-
-/** Quick settings tile: Airplane mode **/
-public class QAirplaneTile extends AirplaneModeTile {
-
-    public QAirplaneTile(Host host) {
-        super(host);
-    }
-
-    @Override
-    public QSTileBaseView createTileView(Context context) {
-        return new QSQuickTileView(context);
-    }
-
-    @Override
-    public int getTileType() {
-        return QSTileView.QS_TYPE_QUICK;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QBluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QBluetoothTile.java
deleted file mode 100644
index 4fe7e45..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QBluetoothTile.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.qs.tiles;
-
-import android.content.Context;
-import com.android.systemui.QSQuickTileView;
-import com.android.systemui.qs.QSTileBaseView;
-import com.android.systemui.qs.QSTileView;
-
-/** Quick settings tile: Bluetooth **/
-public class QBluetoothTile extends BluetoothTile  {
-
-    public QBluetoothTile(Host host) {
-        super(host, false);
-    }
-
-    @Override
-    public QSTileBaseView createTileView(Context context) {
-        return new QSQuickTileView(context);
-    }
-
-    @Override
-    public int getTileType() {
-        return QSTileView.QS_TYPE_QUICK;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QFlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QFlashlightTile.java
deleted file mode 100644
index e115755e..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QFlashlightTile.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.qs.tiles;
-
-import android.content.Context;
-import com.android.systemui.QSQuickTileView;
-import com.android.systemui.qs.QSTileBaseView;
-import com.android.systemui.qs.QSTileView;
-
-/** Quick settings tile: Flashlight **/
-public class QFlashlightTile extends FlashlightTile {
-
-    public QFlashlightTile(Host host) {
-        super(host);
-    }
-
-    @Override
-    public QSTileBaseView createTileView(Context context) {
-        return new QSQuickTileView(context);
-    }
-
-    @Override
-    public int getTileType() {
-        return QSTileView.QS_TYPE_QUICK;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QLockTile.java
deleted file mode 100644
index 8b3013a..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QLockTile.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.qs.tiles;
-
-import android.content.Context;
-import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.QSQuickTileView;
-import com.android.systemui.R;
-import com.android.systemui.qs.QSTile;
-import com.android.systemui.qs.QSTileBaseView;
-import com.android.systemui.qs.QSTileView;
-import com.android.systemui.statusbar.policy.KeyguardMonitor;
-
-public class QLockTile extends QSTile<QSTile.State> implements KeyguardMonitor.Callback {
-
-    private final KeyguardMonitor mKeyguard;
-
-    public QLockTile(Host host) {
-        super(host);
-        mKeyguard = host.getKeyguardMonitor();
-    }
-
-    @Override
-    public QSTileBaseView createTileView(Context context) {
-        return new QSQuickTileView(context);
-    }
-
-    @Override
-    public int getTileType() {
-        return QSTileView.QS_TYPE_QUICK;
-    }
-
-    @Override
-    protected State newTileState() {
-        return new State();
-    }
-
-    @Override
-    public void setListening(boolean listening) {
-        if (listening) {
-            mKeyguard.addCallback(this);
-        } else {
-            mKeyguard.removeCallback(this);
-        }
-    }
-
-    @Override
-    public int getMetricsCategory() {
-        return MetricsLogger.QS_LOCK_TILE;
-    }
-
-    @Override
-    public void onKeyguardChanged() {
-        refreshState();
-    }
-
-    @Override
-    protected void handleClick() {
-        if (mKeyguard.isShowing()) {
-            mKeyguard.unlock();
-        } else {
-            mKeyguard.lock();
-        }
-    }
-
-    @Override
-    protected void handleUpdateState(State state, Object arg) {
-        // TOD: Content description.
-        state.visible = true;
-        if (mKeyguard.isShowing()) {
-            state.icon = ResourceIcon.get(R.drawable.ic_qs_lock);
-        } else {
-            state.icon = ResourceIcon.get(R.drawable.ic_qs_lock_open);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QRotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QRotationLockTile.java
deleted file mode 100644
index 5f5cab5..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QRotationLockTile.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.qs.tiles;
-
-import android.content.Context;
-import com.android.systemui.QSQuickTileView;
-import com.android.systemui.qs.QSTileBaseView;
-import com.android.systemui.qs.QSTileView;
-
-/** Quick settings tile: Rotation **/
-public class QRotationLockTile extends RotationLockTile {
-
-    public QRotationLockTile(Host host) {
-        super(host);
-    }
-
-    @Override
-    public QSTileBaseView createTileView(Context context) {
-        return new QSQuickTileView(context);
-    }
-
-    @Override
-    public int getTileType() {
-        return QSTileView.QS_TYPE_QUICK;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QWifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QWifiTile.java
deleted file mode 100644
index f0fe87d..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QWifiTile.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.qs.tiles;
-
-import android.content.Context;
-import com.android.systemui.QSQuickTileView;
-import com.android.systemui.qs.QSTileBaseView;
-import com.android.systemui.qs.QSTileView;
-import com.android.systemui.statusbar.policy.WifiIcons;
-
-/** Quick settings tile: Wifi **/
-public class QWifiTile extends WifiTile {
-
-    public QWifiTile(Host host) {
-        super(host, false);
-    }
-
-    @Override
-    public QSTileBaseView createTileView(Context context) {
-        return new QSQuickTileView(context);
-    }
-
-    @Override
-    public int getTileType() {
-        return QSTileView.QS_TYPE_QUICK;
-    }
-
-    @Override
-    protected void handleUpdateState(SignalState state, Object arg) {
-        super.handleUpdateState(state, arg);
-
-        CallbackInfo cb = (CallbackInfo) arg;
-        if (cb == null) {
-            cb = mSignalCallback.mInfo;
-        }
-        boolean wifiConnected = cb.enabled && (cb.wifiSignalIconId > 0) && (cb.enabledDesc != null);
-
-        if (state.enabled && wifiConnected) {
-            // Only show full signal here.
-            state.icon = ResourceIcon.get(WifiIcons.QS_WIFI_SIGNAL_STRENGTH[1][4]);
-        }
-        // No activity in the quick toggle.
-        state.activityIn = false;
-        state.activityOut = false;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
index 1a26a4d..d85cf60 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
@@ -72,7 +72,8 @@
         final boolean rotationLocked = arg != null ? ((UserBoolean) arg).value
                 : mController.isRotationLocked();
         final boolean userInitiated = arg != null ? ((UserBoolean) arg).userInitiated : false;
-        state.visible = mController.isRotationLockAffordanceVisible();
+        // TODO: Handle accessibility rotation lock and whatnot.
+//        state.visible = mController.isRotationLockAffordanceVisible();
         if (state.value == rotationLocked && state.contentDescription != null) {
             // No change and initialized, no need to update all the values.
             return;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
index 3c5ab8d..d29cae4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserTile.java
@@ -67,17 +67,19 @@
     @Override
     protected void handleUpdateState(State state, Object arg) {
         final Pair<String, Drawable> p = arg != null ? (Pair<String, Drawable>) arg : mLastUpdate;
-        state.visible = p != null;
-        if (!state.visible) return;
-        state.label = p.first;
-        // TODO: Better content description.
-        state.contentDescription = p.first;
-        state.icon = new Icon() {
-            @Override
-            public Drawable getDrawable(Context context) {
-                return p.second;
-            }
-        };
+        if (p != null) {
+            state.label = p.first;
+            // TODO: Better content description.
+            state.contentDescription = p.first;
+            state.icon = new Icon() {
+                @Override
+                public Drawable getDrawable(Context context) {
+                    return p.second;
+                }
+            };
+        } else {
+            // TODO: Default state.
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 7f4442a..48b4096 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -18,20 +18,19 @@
 
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.provider.Settings;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
-
 import com.android.internal.logging.MetricsLogger;
 import com.android.settingslib.wifi.AccessPoint;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSDetailItems;
 import com.android.systemui.qs.QSDetailItems.Item;
+import com.android.systemui.qs.QSIconView;
 import com.android.systemui.qs.QSTile;
-import com.android.systemui.qs.QSTileBaseView;
-import com.android.systemui.qs.QSTileView;
 import com.android.systemui.qs.SignalTileView;
 import com.android.systemui.statusbar.policy.NetworkController;
 import com.android.systemui.statusbar.policy.NetworkController.AccessPointController;
@@ -51,22 +50,14 @@
 
     protected final WifiSignalCallback mSignalCallback = new WifiSignalCallback();
 
-    private final boolean mAlwaysDetail;
-
-    public WifiTile(Host host, boolean alwaysDetail) {
+    public WifiTile(Host host) {
         super(host);
-        mAlwaysDetail = alwaysDetail;
         mController = host.getNetworkController();
         mWifiController = mController.getAccessPointController();
         mDetailAdapter = new WifiDetailAdapter();
     }
 
     @Override
-    public int getTileType() {
-        return QSTileView.QS_TYPE_DUAL;
-    }
-
-    @Override
     protected SignalState newTileState() {
         return new SignalState();
     }
@@ -95,23 +86,20 @@
     }
 
     @Override
-    public QSTileBaseView createTileView(Context context) {
+    public QSIconView createTileView(Context context) {
         return new SignalTileView(context);
     }
 
     @Override
-    protected void handleClick() {
-        if (mAlwaysDetail) {
-            handleSecondaryClick();
-            return;
-        }
+    protected void handleSecondaryClick() {
+        // Secondary clicks are header clicks, just toggle.
         mState.copyTo(mStateBeforeClick);
         MetricsLogger.action(mContext, getMetricsCategory(), !mState.enabled);
         mController.setWifiEnabled(!mState.enabled);
     }
 
     @Override
-    protected void handleSecondaryClick() {
+    protected void handleClick() {
         if (!mWifiController.canConfigWifi()) {
             mHost.startActivityDismissingKeyguard(new Intent(Settings.ACTION_WIFI_SETTINGS));
             return;
@@ -125,7 +113,6 @@
 
     @Override
     protected void handleUpdateState(SignalState state, Object arg) {
-        state.visible = true;
         if (DEBUG) Log.d(TAG, "handleUpdateState arg=" + arg);
         CallbackInfo cb = (CallbackInfo) arg;
         if (cb == null) {
@@ -201,6 +188,10 @@
         return string;
     }
 
+    public static boolean isSupported(Host host) {
+        return host.getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI);
+    }
+
     protected static final class CallbackInfo {
         boolean enabled;
         boolean connected;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
new file mode 100644
index 0000000..07915f8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WorkModeTile.java
@@ -0,0 +1,208 @@
+/*
+ * 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.qs.tiles;
+
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.UserInfo;
+import android.os.UserHandle;
+import android.os.UserManager;
+import com.android.internal.logging.MetricsLogger;
+import com.android.systemui.R;
+import com.android.systemui.qs.QSTile;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/** Quick settings tile: Work profile on/off */
+public class WorkModeTile extends QSTile<QSTile.BooleanState> {
+    private final AnimationIcon mEnable =
+            new AnimationIcon(R.drawable.ic_signal_workmode_enable_animation);
+    private final AnimationIcon mDisable =
+            new AnimationIcon(R.drawable.ic_signal_workmode_disable_animation);
+
+    private boolean mListening;
+
+    private UserManager mUserManager;
+    private List<UserInfo> mProfiles;
+
+    public WorkModeTile(Host host) {
+        super(host);
+        mUserManager = UserManager.get(mContext);
+        mProfiles = new LinkedList<UserInfo>();
+    }
+
+    @Override
+    protected BooleanState newTileState() {
+        return new BooleanState();
+    }
+
+    @Override
+    public void handleClick() {
+        MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
+        setWorkModeEnabled(!mState.value);
+    }
+
+    private void reloadManagedProfiles(int userHandle) {
+        synchronized (mProfiles) {
+            mProfiles.clear();
+
+            if (userHandle == UserHandle.USER_CURRENT) {
+                userHandle = ActivityManager.getCurrentUser();
+            }
+            for (UserInfo ui : mUserManager.getEnabledProfiles(userHandle)) {
+                if (ui.isManagedProfile()) {
+                    mProfiles.add(ui);
+                }
+            }
+        }
+    }
+
+    private boolean hasActiveProfile() {
+        synchronized (mProfiles) {
+            return mProfiles.size() > 0;
+        }
+    }
+
+    private boolean isWorkModeEnabled() {
+        synchronized (mProfiles) {
+            for (UserInfo ui : mProfiles) {
+                if (ui.isQuietModeEnabled()) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+    private void refreshQuietModeState(boolean backgroundRefresh) {
+        if (backgroundRefresh) {
+            refreshState(isWorkModeEnabled() ? UserBoolean.BACKGROUND_TRUE
+                    : UserBoolean.BACKGROUND_FALSE);
+        } else {
+            refreshState(isWorkModeEnabled() ? UserBoolean.USER_TRUE : UserBoolean.USER_FALSE);
+        }
+    }
+
+    @Override
+    protected void handleUpdateState(BooleanState state, Object arg) {
+        if (!hasActiveProfile()) {
+            mHost.removeTile(getTileSpec());
+            return;
+        }
+
+        final boolean userInitialized;
+        if (arg instanceof UserBoolean) {
+            state.value = ((UserBoolean) arg).value;
+            userInitialized = ((UserBoolean) arg).userInitiated;
+        } else {
+            state.value = isWorkModeEnabled();
+            userInitialized = false;
+        }
+
+        final AnimationIcon icon;
+        state.label = mContext.getString(R.string.quick_settings_work_mode_label);
+        if (state.value) {
+            icon = mEnable;
+            state.contentDescription =  mContext.getString(
+                    R.string.accessibility_quick_settings_work_mode_on);
+        } else {
+            icon = mDisable;
+            state.contentDescription =  mContext.getString(
+                    R.string.accessibility_quick_settings_work_mode_off);
+        }
+        icon.setAllowAnimation(userInitialized);
+        state.icon = icon;
+    }
+
+    @Override
+    public int getMetricsCategory() {
+        return MetricsLogger.QS_WORKMODE;
+    }
+
+    @Override
+    protected String composeChangeAnnouncement() {
+        if (mState.value) {
+            return mContext.getString(R.string.accessibility_quick_settings_work_mode_changed_on);
+        } else {
+            return mContext.getString(R.string.accessibility_quick_settings_work_mode_changed_off);
+        }
+    }
+
+    @Override
+    public void setListening(boolean listening) {
+        if (mListening == listening) {
+            return;
+        }
+        mListening = listening;
+        if (listening) {
+            reloadManagedProfiles(UserHandle.USER_CURRENT);
+
+            final IntentFilter filter = new IntentFilter();
+            filter.addAction(Intent.ACTION_USER_SWITCHED);
+            filter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED);
+            filter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
+            filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED);
+            mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null);
+        } else {
+            mContext.unregisterReceiver(mReceiver);
+        }
+    }
+
+    private void setWorkModeEnabled(boolean enabled) {
+        synchronized (mProfiles) {
+            for (UserInfo ui : mProfiles) {
+                mUserManager.setQuietModeEnabled(ui.id, !enabled);
+            }
+        }
+    }
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            final int targetUser;
+            final boolean isBackgroundRefresh;
+            switch (action) {
+                case Intent.ACTION_USER_SWITCHED:
+                    targetUser = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
+                            UserHandle.USER_CURRENT);
+                    isBackgroundRefresh = true;
+                    break;
+                case Intent.ACTION_MANAGED_PROFILE_ADDED:
+                case Intent.ACTION_MANAGED_PROFILE_REMOVED:
+                    targetUser = UserHandle.USER_CURRENT;
+                    isBackgroundRefresh = true;
+                    break;
+                case Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED:
+                    targetUser = UserHandle.USER_CURRENT;
+                    isBackgroundRefresh = false;
+                    break;
+               default:
+                   targetUser = UserHandle.USER_NULL;
+                   isBackgroundRefresh = false;
+            }
+            if (targetUser != UserHandle.USER_NULL) {
+                reloadManagedProfiles(targetUser);
+                refreshQuietModeState(isBackgroundRefresh);
+            }
+        }
+    };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 5d17e2c..8979843 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -52,6 +52,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.util.ArraySet;
 import android.util.Log;
 import android.util.MutableBoolean;
 import android.util.Pair;
@@ -154,7 +155,7 @@
 
     /** Returns a list of the recents tasks */
     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int numLatestTasks, int userId,
-            boolean isTopTaskHome) {
+            boolean isTopTaskHome, ArraySet<Integer> quietProfileIds) {
         if (mAm == null) return null;
 
         // If we are mocking, then create some recent tasks
@@ -215,6 +216,8 @@
             // tasks if it is not the first active task.
             boolean isExcluded = (t.baseIntent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
                     == Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
+            // Filter out recent tasks from managed profiles which are in quiet mode.
+            isExcluded |= quietProfileIds.contains(t.userId);
             if (isExcluded && (isTopTaskHome || !isFirstValidTask)) {
                 iter.remove();
                 continue;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
index 63d09ee..1845bf9 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -18,10 +18,13 @@
 
 import android.app.ActivityManager;
 import android.content.Context;
+import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
 import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.ArraySet;
 import android.util.Log;
 import com.android.systemui.Prefs;
 import com.android.systemui.recents.Recents;
@@ -66,20 +69,42 @@
 
     List<ActivityManager.RecentTaskInfo> mRawTasks;
     TaskStack mStack;
+    ArraySet<Integer> mCurrentQuietProfiles = new ArraySet<Integer>();
 
     /** Package level ctor */
     RecentsTaskLoadPlan(Context context) {
         mContext = context;
     }
 
+    private void updateCurrentQuietProfilesCache(int currentUserId) {
+        mCurrentQuietProfiles.clear();
+
+        if (currentUserId == UserHandle.USER_CURRENT) {
+            currentUserId = ActivityManager.getCurrentUser();
+        }
+        UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        List<UserInfo> profiles = userManager.getProfiles(currentUserId);
+        if (profiles != null) {
+            for (int i = 0; i < profiles.size(); i++) {
+                UserInfo user  = profiles.get(i);
+                if (user.isManagedProfile() && user.isQuietModeEnabled()) {
+                    mCurrentQuietProfiles.add(user.id);
+                }
+            }
+        }
+    }
+
     /**
      * An optimization to preload the raw list of tasks.  The raw tasks are saved in least-recent
      * to most-recent order.
      */
     public synchronized void preloadRawTasks(boolean isTopTaskHome) {
+        int currentUserId = UserHandle.USER_CURRENT;
+        updateCurrentQuietProfilesCache(currentUserId);
         SystemServicesProxy ssp = Recents.getSystemServices();
         mRawTasks = ssp.getRecentTasks(ActivityManager.getMaxRecentTasksStatic(),
-                UserHandle.CURRENT.getIdentifier(), isTopTaskHome);
+                currentUserId, isTopTaskHome, mCurrentQuietProfiles);
+
         // Since the raw tasks are given in most-recent to least-recent order, we need to reverse it
         Collections.reverse(mRawTasks);
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
index 757d2aa..f646a92 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
@@ -46,19 +46,6 @@
                 }
             };
 
-    public static final Property<AnimateableViewBounds, Integer> CLIP_RIGHT =
-            new IntProperty<AnimateableViewBounds>("clipRight") {
-                @Override
-                public void setValue(AnimateableViewBounds object, int clip) {
-                    object.setClipRight(clip, false /* force */);
-                }
-
-                @Override
-                public Integer get(AnimateableViewBounds object) {
-                    return object.getClipRight();
-                }
-            };
-
     public AnimateableViewBounds(View source, int cornerRadius) {
         mSourceView = source;
         mCornerRadius = cornerRadius;
@@ -102,19 +89,6 @@
         return mClipRect.bottom;
     }
 
-    /** Sets the right clip. */
-    public void setClipRight(int right, boolean force) {
-        if (right != mClipRect.right || force) {
-            mClipRect.right = right;
-            updateClipBounds();
-        }
-    }
-
-    /** Returns the right clip. */
-    public int getClipRight() {
-        return mClipRect.right;
-    }
-
     private void updateClipBounds() {
         mClipBounds.set(mClipRect.left, mClipRect.top,
                 mSourceView.getWidth() - mClipRect.right,
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
index 9b9d58c..2351aa3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
@@ -19,7 +19,6 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.util.Log;
-import com.android.systemui.recents.misc.Utilities;
 import com.android.systemui.recents.model.Task;
 
 import java.util.Collections;
@@ -80,7 +79,6 @@
                 float width = normalizedTaskWidths[i] * rowScale;
                 if (rowWidth + width > normalizedWorkspaceWidth) {
                     // That is too long for this row, create new row
-                    rowWidth = 0f;
                     if ((rowCount + 1) * rowScale > normalizedWorkspaceHeight) {
                         // The new row is too high, so we need to try fitting again.  Update the
                         // scale to be the smaller of the scale needed to fit the task in the
@@ -88,9 +86,11 @@
                         rowScale = Math.min(normalizedWorkspaceWidth / (rowWidth + width),
                                 normalizedWorkspaceHeight / (rowCount + 1));
                         rowCount = 1;
+                        rowWidth = 0;
                         i = 0;
                     } else {
                         // The new row fits, so continue
+                        rowWidth = width;
                         rowCount++;
                         i++;
                     }
@@ -103,20 +103,20 @@
             }
 
             // Normalize each of the actual rects to that scale
-            int height = (int) (rowScale * workspaceHeight);
-            float rowTop = ((1f - (rowScale * rowCount)) * workspaceHeight) / 2f;
             float defaultRowLeft = ((1f - (maxRowWidth / normalizedWorkspaceWidth)) *
                     workspaceWidth) / 2f;
             float rowLeft = defaultRowLeft;
+            float rowTop = ((1f - (rowScale * rowCount)) * workspaceHeight) / 2f;
+            float rowHeight = rowScale * workspaceHeight;
             for (int i = 0; i < numFreeformTasks; i++) {
                 Task task = freeformTasks.get(i);
-                int width = (int) (height * normalizedTaskWidths[i]);
+                float width = rowHeight * normalizedTaskWidths[i];
                 if (rowLeft + width > workspaceWidth) {
                     // This goes on the next line
-                    rowTop += height;
+                    rowTop += rowHeight;
                     rowLeft = defaultRowLeft;
                 }
-                RectF rect = new RectF(rowLeft, rowTop, rowLeft + width, rowTop + height);
+                RectF rect = new RectF(rowLeft, rowTop, rowLeft + width, rowTop + rowHeight);
                 rowLeft += width;
                 mTaskRectMap.put(task.key, rect);
             }
@@ -140,34 +140,29 @@
     public TaskViewTransform getTransform(Task task, TaskViewTransform transformOut,
             TaskStackLayoutAlgorithm stackLayout) {
         if (mTaskRectMap.containsKey(task.key)) {
-            Rect taskRect = stackLayout.mTaskRect;
-            RectF ffRect = mTaskRectMap.get(task.key);
-            float scale = Math.max(ffRect.width() / taskRect.width(),
-                    ffRect.height() / taskRect.height());
-            int topOffset = (stackLayout.mFreeformRect.top - taskRect.top);
-            int scaleXOffset = (int) (((1f - scale) * taskRect.width()) / 2);
-            int scaleYOffset = (int) (((1f - scale) * taskRect.height()) / 2);
+            final Rect taskRect = stackLayout.mTaskRect;
+            final RectF ffRect = mTaskRectMap.get(task.key);
 
-            transformOut.scale = scale * 0.95f;
-            transformOut.translationX = (int) (ffRect.left - scaleXOffset);
-            transformOut.translationY = (int) (topOffset + ffRect.top - scaleYOffset);
+            transformOut.scale = 1f;
+            transformOut.alpha = 1f;
             transformOut.translationZ = stackLayout.mMaxTranslationZ;
-            transformOut.clipBottom = (int) (taskRect.height() - (ffRect.height() / scale));
-            transformOut.clipRight = (int) (taskRect.width() - (ffRect.width() / scale));
             if (task.thumbnail != null) {
-                transformOut.thumbnailScale = Math.min(
-                        ((float) taskRect.width() - transformOut.clipRight) /
-                                task.thumbnail.getWidth(),
-                        ((float) taskRect.height() - transformOut.clipBottom) /
-                                task.thumbnail.getHeight());
+                if (task.bounds == null) {
+                    // This is a stack task that has no freeform thumbnail, so keep the same bitmap
+                    // scale as it had in the stack
+                    transformOut.thumbnailScale = (float) taskRect.width() /
+                            task.thumbnail.getWidth();
+                } else {
+                    // This is a freeform rect so fit the bitmap to the task bounds
+                    transformOut.thumbnailScale = Math.min(
+                            ffRect.width() / task.thumbnail.getWidth(),
+                            ffRect.height() / task.thumbnail.getHeight());
+                }
             } else {
                 transformOut.thumbnailScale = 1f;
             }
-            transformOut.rect.set(taskRect);
-            transformOut.rect.offset(transformOut.translationX, transformOut.translationY);
-            Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
-            transformOut.rect.right -= transformOut.clipRight * scale;
-            transformOut.rect.bottom -= transformOut.clipBottom * scale;
+            transformOut.rect.set(ffRect);
+            transformOut.rect.offset(stackLayout.mFreeformRect.left, stackLayout.mFreeformRect.top);
             transformOut.visible = true;
             transformOut.p = 1f;
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index a0a1bac..55a54a2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -142,7 +142,8 @@
     public void setTaskStack(TaskStack stack) {
         RecentsConfiguration config = Recents.getConfiguration();
         mStack = stack;
-        if (config.getLaunchState().launchedReuseTaskStackViews) {
+        // Disable reusing task stack views until the visibility bug is fixed. b/25998134
+        if (false && config.getLaunchState().launchedReuseTaskStackViews) {
             if (mTaskStackView != null) {
                 // If onRecentsHidden is not triggered, we need to the stack view again here
                 mTaskStackView.reset();
@@ -411,6 +412,8 @@
             RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
             if (launchState.launchedViaDragGesture) {
                 setTranslationY(getMeasuredHeight());
+            } else {
+                setTranslationY(0f);
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
index 7d5daae..f599f52 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -507,6 +507,15 @@
     }
 
     /**
+     * Returns the task progress that would put the task just off the back of the stack.
+     */
+    public float getStackBackTaskProgress(float stackScroll) {
+        float min = mUnfocusedRange.relativeMin +
+                mFocusState * (mFocusedRange.relativeMin - mUnfocusedRange.relativeMin);
+        return stackScroll + min;
+    }
+
+    /**
      * Returns the task progress that would put the task just off the front of the stack.
      */
     public float getStackFrontTaskProgress(float stackScroll) {
@@ -647,6 +656,7 @@
             return transformOut;
         }
 
+        int x = (mStackRect.width() - mTaskRect.width()) / 2;
         int y;
         float z;
         float relP;
@@ -671,16 +681,13 @@
 
         // Fill out the transform
         transformOut.scale = 1f;
-        transformOut.translationX = (mStackRect.width() - mTaskRect.width()) / 2;
-        transformOut.translationY = y;
+        transformOut.alpha = 1f;
         transformOut.translationZ = z;
         transformOut.rect.set(mTaskRect);
-        transformOut.rect.offset(transformOut.translationX, transformOut.translationY);
+        transformOut.rect.offset(x, y);
         Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
         transformOut.visible = (transformOut.rect.top < mStackRect.bottom) &&
                 (frontTransform == null || transformOut.rect.top != frontTransform.rect.top);
-        transformOut.clipBottom = 0;
-        transformOut.clipRight = 0;
         transformOut.thumbnailScale = 1f;
         transformOut.p = relP;
         return transformOut;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index cc5aaae..350bc2b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -20,11 +20,12 @@
 import android.animation.ValueAnimator;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.graphics.RectF;
-import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
 import android.os.Bundle;
 import android.util.IntProperty;
 import android.util.Log;
@@ -94,15 +95,15 @@
     private static final float SHOW_HISTORY_BUTTON_SCROLL_THRESHOLD = 0.3f;
     private static final float HIDE_HISTORY_BUTTON_SCROLL_THRESHOLD = 0.3f;
 
-    public static final Property<ColorDrawable, Integer> COLOR_DRAWABLE_ALPHA =
-            new IntProperty<ColorDrawable>("colorDrawableAlpha") {
+    public static final Property<Drawable, Integer> DRAWABLE_ALPHA =
+            new IntProperty<Drawable>("drawableAlpha") {
                 @Override
-                public void setValue(ColorDrawable object, int alpha) {
+                public void setValue(Drawable object, int alpha) {
                     object.setAlpha(alpha);
                 }
 
                 @Override
-                public Integer get(ColorDrawable object) {
+                public Integer get(Drawable object) {
                     return object.getAlpha();
                 }
             };
@@ -118,7 +119,7 @@
     TaskStackViewScroller mStackScroller;
     TaskStackViewTouchHandler mTouchHandler;
     TaskStackViewCallbacks mCb;
-    ColorDrawable mFreeformWorkspaceBackground;
+    GradientDrawable mFreeformWorkspaceBackground;
     ObjectAnimator mFreeformWorkspaceBackgroundAnimator;
     ViewPool<TaskView, Task> mViewPool;
     ArrayList<TaskViewTransform> mCurrentTaskTransforms = new ArrayList<>();
@@ -126,6 +127,7 @@
     Task mFocusedTask;
     // Optimizations
     int mStackViewsAnimationDuration;
+    int mTaskCornerRadiusPx;
     boolean mStackViewsDirty = true;
     boolean mStackViewsClipDirty = true;
     boolean mAwaitingFirstLayout = true;
@@ -174,6 +176,9 @@
 
     public TaskStackView(Context context, TaskStack stack) {
         super(context);
+        SystemServicesProxy ssp = Recents.getSystemServices();
+        Resources res = context.getResources();
+
         // Set the stack first
         setStack(stack);
         mViewPool = new ViewPool<>(context, this);
@@ -184,6 +189,8 @@
         mTouchHandler = new TaskStackViewTouchHandler(context, this, mStackScroller);
         mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
                 com.android.internal.R.interpolator.fast_out_slow_in);
+        mTaskCornerRadiusPx = res.getDimensionPixelSize(
+                R.dimen.recents_task_view_rounded_corners_radius);
 
         int taskBarDismissDozeDelaySeconds = getResources().getInteger(
                 R.integer.recents_task_bar_dismiss_delay_seconds);
@@ -201,8 +208,12 @@
         });
         setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
 
-        mFreeformWorkspaceBackground = new ColorDrawable(0x33000000);
+        mFreeformWorkspaceBackground = (GradientDrawable) getContext().getDrawable(
+                R.drawable.recents_freeform_workspace_bg);
         mFreeformWorkspaceBackground.setCallback(this);
+        if (ssp.hasFreeformWorkspaceSupport()) {
+            setBackgroundColor(getContext().getColor(R.color.recents_freeform_workspace_bg_color));
+        }
     }
 
     /** Sets the callbacks */
@@ -364,8 +375,7 @@
     private boolean updateStackTransforms(ArrayList<TaskViewTransform> taskTransforms,
                                        ArrayList<Task> tasks,
                                        float stackScroll,
-                                       int[] visibleRangeOut,
-                                       boolean boundTranslationsToRect) {
+                                       int[] visibleRangeOut) {
         int taskTransformCount = taskTransforms.size();
         int taskCount = tasks.size();
         int frontMostVisibleIndex = -1;
@@ -411,11 +421,6 @@
                     break;
                 }
             }
-
-            if (boundTranslationsToRect) {
-                transform.translationY = Math.min(transform.translationY,
-                        mLayoutAlgorithm.mStackRect.bottom);
-            }
             frontTransform = transform;
         }
         if (visibleRangeOut != null) {
@@ -433,7 +438,7 @@
             float stackScroll = mStackScroller.getStackScroll();
             int[] visibleStackRange = mTmpVisibleRange;
             boolean isValidVisibleStackRange = updateStackTransforms(mCurrentTaskTransforms, tasks,
-                    stackScroll, visibleStackRange, false);
+                    stackScroll, visibleStackRange);
             boolean hasStackBackTransform = false;
             boolean hasStackFrontTransform = false;
             if (DEBUG) {
@@ -490,7 +495,7 @@
                 }
 
                 // Animate the task into place
-                tv.updateViewPropertiesToTaskTransform(transform, transform.clipBottom,
+                tv.updateViewPropertiesToTaskTransform(transform, 0,
                         mStackViewsAnimationDuration, mFastOutSlowInInterpolator,
                         mRequestUpdateClippingListener);
 
@@ -513,8 +518,9 @@
                         if (Float.compare(transform.p, 0f) <= 0) {
                             if (!hasStackBackTransform) {
                                 hasStackBackTransform = true;
-                                mLayoutAlgorithm.getStackTransform(0f, 0f, mTmpStackBackTransform,
-                                        null);
+                                mLayoutAlgorithm.getStackTransform(
+                                        mLayoutAlgorithm.getStackBackTaskProgress(0f), 0f,
+                                        mTmpStackBackTransform, null);
                             }
                             tv.updateViewPropertiesToTaskTransform(mTmpStackBackTransform, 0, 0,
                                     mFastOutSlowInInterpolator, mRequestUpdateClippingListener);
@@ -586,17 +592,11 @@
                 // stacked and we can make assumptions about the visibility of the this
                 // task relative to the ones in front of it.
                 if (frontTv != null) {
-                    mTmpTaskRect.set(mLayoutAlgorithm.mTaskRect);
-                    mTmpTaskRect.offset(0, tv.getTranslationY());
-                    Utilities.scaleRectAboutCenter(mTmpTaskRect, tv.getScaleX());
-                    float taskBottom = mTmpTaskRect.bottom;
-                    mTmpTaskRect.set(mLayoutAlgorithm.mTaskRect);
-                    mTmpTaskRect.offset(0, frontTv.getTranslationY());
-                    Utilities.scaleRectAboutCenter(mTmpTaskRect, frontTv.getScaleX());
-                    float frontTaskTop = mTmpTaskRect.top;
+                    float taskBottom = tv.getBottom();
+                    float frontTaskTop = frontTv.getTop();
                     if (frontTaskTop < taskBottom) {
                         // Map the stack view space coordinate (the rects) to view space
-                        clipBottom = (int) ((taskBottom - frontTaskTop) / tv.getScaleX()) - 1;
+                        clipBottom = (int) (taskBottom - frontTaskTop) - mTaskCornerRadiusPx;
                     }
                 }
             }
@@ -980,11 +980,11 @@
             onFirstLayout();
         }
 
+        requestSynchronizeStackViewsWithModel();
         if (changed) {
             if (mStackScroller.isScrollOutOfBounds()) {
                 mStackScroller.boundScroll();
             }
-            requestSynchronizeStackViewsWithModel();
             synchronizeStackViewsWithModel();
             requestUpdateStackViewsClip();
             clipTaskViews(true /* forceUpdate */);
@@ -1147,8 +1147,7 @@
         transformPointToViewLocal(point, tv);
         x = point[0];
         y = point[1];
-        return (0 <= x) && (x < (tv.getMeasuredWidth() - tv.getViewBounds().getClipRight())) &&
-                (0 <= y) && (y < (tv.getMeasuredHeight() - tv.getViewBounds().getClipBottom()));
+        return (0 <= x) && (x < tv.getWidth()) && (0 <= y) && (y < tv.getHeight());
     }
 
     @Override
@@ -1221,14 +1220,13 @@
             } else if (pullStackForward) {
                 // Otherwise, offset the scroll by the movement of the anchor task
                 float anchorTaskScroll = mLayoutAlgorithm.getStackScrollForTask(anchorTask);
-                float newStackScroll = mStackScroller.getStackScroll() +
-                        (anchorTaskScroll - prevAnchorTaskScroll);
+                float stackScrollOffset = (anchorTaskScroll - prevAnchorTaskScroll);
                 if (mLayoutAlgorithm.getFocusState() != TaskStackLayoutAlgorithm.STATE_FOCUSED) {
                     // If we are focused, we don't want the front task to move, but otherwise, we
                     // allow the back task to move up, and the front task to move back
-                    newStackScroll /= 2;
+                    stackScrollOffset /= 2;
                 }
-                mStackScroller.setStackScroll(newStackScroll);
+                mStackScroller.setStackScroll(mStackScroller.getStackScroll() + stackScrollOffset);
                 mStackScroller.boundScroll();
             }
 
@@ -1498,6 +1496,18 @@
         event.taskView.animate()
                 .withEndAction(event.postAnimationTrigger.decrementAsRunnable());
 
+        // We translated the view but we need to animate it back from the current layout-space rect
+        // to its final layout-space rect
+        int x = (int) event.taskView.getTranslationX();
+        int y = (int) event.taskView.getTranslationY();
+        Rect taskViewRect = new Rect(event.taskView.getLeft(), event.taskView.getTop(),
+                event.taskView.getRight(), event.taskView.getBottom());
+        taskViewRect.offset(x, y);
+        event.taskView.setTranslationX(0);
+        event.taskView.setTranslationY(0);
+        event.taskView.setLeftTopRightBottom(taskViewRect.left, taskViewRect.top,
+                taskViewRect.right, taskViewRect.bottom);
+
         // Animate the tack view back into position
         requestSynchronizeStackViewsWithModel(250);
     }
@@ -1582,7 +1592,7 @@
 
         Utilities.cancelAnimationWithoutCallbacks(mFreeformWorkspaceBackgroundAnimator);
         mFreeformWorkspaceBackgroundAnimator = ObjectAnimator.ofInt(mFreeformWorkspaceBackground,
-                COLOR_DRAWABLE_ALPHA, mFreeformWorkspaceBackground.getAlpha(), targetAlpha);
+                DRAWABLE_ALPHA, mFreeformWorkspaceBackground.getAlpha(), targetAlpha);
         mFreeformWorkspaceBackgroundAnimator.setDuration(duration);
         mFreeformWorkspaceBackgroundAnimator.setInterpolator(interpolator);
         mFreeformWorkspaceBackgroundAnimator.start();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index 813a1fc..1e2227e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -179,6 +179,13 @@
     }
 
     @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+        mHeaderView.onTaskViewSizeChanged(w, h);
+        mThumbnailView.onTaskViewSizeChanged(w, h);
+    }
+
+    @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
         if (ev.getAction() == MotionEvent.ACTION_DOWN) {
             mDownTouchPos.set((int) (ev.getX() * getScaleX()), (int) (ev.getY() * getScaleY()));
@@ -232,8 +239,14 @@
             mClipAnimation.playTogether(
                     ObjectAnimator.ofInt(mViewBounds, AnimateableViewBounds.CLIP_BOTTOM,
                             mViewBounds.getClipBottom(), clipBottom),
-                    ObjectAnimator.ofInt(mViewBounds, AnimateableViewBounds.CLIP_RIGHT,
-                            mViewBounds.getClipRight(), toTransform.clipRight),
+                    ObjectAnimator.ofInt(this, TaskViewTransform.LEFT, getLeft(),
+                            (int) toTransform.rect.left),
+                    ObjectAnimator.ofInt(this, TaskViewTransform.TOP, getTop(),
+                            (int) toTransform.rect.top),
+                    ObjectAnimator.ofInt(this, TaskViewTransform.RIGHT, getRight(),
+                            (int) toTransform.rect.right),
+                    ObjectAnimator.ofInt(this, TaskViewTransform.BOTTOM, getBottom(),
+                            (int) toTransform.rect.bottom),
                     ObjectAnimator.ofFloat(mThumbnailView, TaskViewThumbnail.BITMAP_SCALE,
                             mThumbnailView.getBitmapScale(), toTransform.thumbnailScale));
             mClipAnimation.setStartDelay(toTransform.startDelay);
@@ -242,8 +255,9 @@
             mClipAnimation.start();
         } else {
             mViewBounds.setClipBottom(clipBottom, false /* forceUpdate */);
-            mViewBounds.setClipRight(toTransform.clipRight, false /* forceUpdate */);
             mThumbnailView.setBitmapScale(toTransform.thumbnailScale);
+            setLeftTopRightBottom((int) toTransform.rect.left, (int) toTransform.rect.top,
+                    (int) toTransform.rect.right, (int) toTransform.rect.bottom);
         }
         if (!config.useHardwareLayers) {
             mThumbnailView.updateThumbnailVisibility(clipBottom - getPaddingBottom());
@@ -336,10 +350,10 @@
             } else {
                 // Animate the task up if it was occluding the launch target
                 if (ctx.currentTaskOccludesLaunchTarget) {
-                    setTranslationY(transform.translationY + taskViewAffiliateGroupEnterOffset);
+                    setTranslationY(taskViewAffiliateGroupEnterOffset);
                     setAlpha(0f);
                     animate().alpha(1f)
-                            .translationY(transform.translationY)
+                            .translationY(0)
                             .setUpdateListener(null)
                             .setListener(new AnimatorListenerAdapter() {
                                 private boolean hasEnded;
@@ -372,7 +386,7 @@
                 animate().translationZ(transform.translationZ);
             }
             animate()
-                    .translationY(transform.translationY)
+                    .translationY(0)
                     .setStartDelay(delay)
                     .setUpdateListener(ctx.updateListener)
                     .setListener(new AnimatorListenerAdapter() {
@@ -644,7 +658,6 @@
         }
 
         SystemServicesProxy ssp = Recents.getSystemServices();
-        mHeaderView.onTaskViewFocusChanged(isFocused, animated);
         if (isFocused) {
             if (requestViewFocus && !isFocused()) {
                 requestFocus();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
index 78a2c7f..d8220fd 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -31,6 +31,7 @@
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.GradientDrawable;
 import android.graphics.drawable.RippleDrawable;
+import android.graphics.drawable.ShapeDrawable;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewOutlineProvider;
@@ -55,8 +56,6 @@
 public class TaskViewHeader extends FrameLayout
         implements View.OnClickListener, View.OnLongClickListener {
 
-    private static final float FOCUS_TRANSLATION_Z = 4f;
-
     Task mTask;
 
     // Header views
@@ -66,13 +65,13 @@
     TextView mActivityDescription;
 
     // Header drawables
+    Rect mTaskViewRect = new Rect();
     int mCornerRadius;
     int mHighlightHeight;
     Drawable mLightDismissDrawable;
     Drawable mDarkDismissDrawable;
     RippleDrawable mBackground;
     GradientDrawable mBackgroundColorDrawable;
-    ObjectAnimator mFocusAnimator;
     String mDismissContentDescription;
 
     // Static highlight that we draw at the top of each view
@@ -99,13 +98,6 @@
     public TaskViewHeader(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
         setWillNotDraw(false);
-        setClipToOutline(true);
-        setOutlineProvider(new ViewOutlineProvider() {
-            @Override
-            public void getOutline(View view, Outline outline) {
-                outline.setRect(0, 0, getMeasuredWidth(), getMeasuredHeight());
-            }
-        });
 
         // Load the dismiss resources
         mDimLayerPaint.setColor(Color.argb(0, 0, 0, 0));
@@ -148,8 +140,8 @@
             mApplicationIcon.setBackground(null);
         }
 
-        mBackgroundColorDrawable = (GradientDrawable) getContext().getDrawable(R.drawable
-                .recents_task_view_header_bg_color);
+        mBackgroundColorDrawable = (GradientDrawable) getContext().getDrawable(
+                R.drawable.recents_task_view_header_bg_color);
         // Copy the ripple drawable since we are going to be manipulating it
         mBackground = (RippleDrawable)
                 getContext().getDrawable(R.drawable.recents_task_view_header_bg);
@@ -159,14 +151,37 @@
         setBackground(mBackground);
     }
 
+    /**
+     * Called when the task view frame changes, allowing us to move the contents of the header
+     * to match the frame changes.
+     */
+    public void onTaskViewSizeChanged(int width, int height) {
+        mTaskViewRect.set(0, 0, width, height);
+        if (mDismissButton.getMeasuredWidth() > (width - mApplicationIcon.getMeasuredWidth())) {
+            mDismissButton.setAlpha(0f);
+        } else {
+            mDismissButton.setAlpha(1f);
+            if (mDismissButton != null) {
+                mDismissButton.setTranslationX(width - getMeasuredWidth());
+            }
+        }
+        if (mActivityDescription.getMeasuredWidth() > (width -
+                (mApplicationIcon.getMeasuredWidth() + mDismissButton.getMeasuredWidth()))) {
+            mActivityDescription.setAlpha(0f);
+        } else {
+            mActivityDescription.setAlpha(1f);
+        }
+        invalidate();
+    }
+
     @Override
     protected void onDraw(Canvas canvas) {
         // Draw the highlight at the top edge (but put the bottom edge just out of view)
         float offset = (float) Math.ceil(mHighlightHeight / 2f);
         float radius = mCornerRadius;
         int count = canvas.save(Canvas.CLIP_SAVE_FLAG);
-        canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight());
-        canvas.drawRoundRect(-offset, 0f, (float) getMeasuredWidth() + offset,
+        canvas.clipRect(0, 0, mTaskViewRect.width(), getMeasuredHeight());
+        canvas.drawRoundRect(-offset, 0f, (float) mTaskViewRect.width() + offset,
                 getMeasuredHeight() + radius, radius, radius, sHighlightPaint);
         canvas.restoreToCount(count);
     }
@@ -180,12 +195,6 @@
         invalidate();
     }
 
-    /** Returns the secondary color for a primary color. */
-    int getSecondaryColor(int primaryColor, boolean useLightOverlayColor) {
-        int overlayColor = useLightOverlayColor ? Color.WHITE : Color.BLACK;
-        return Utilities.getColorWithOverlay(primaryColor, overlayColor, 0.8f);
-    }
-
     /** Binds the bar view to the task */
     public void rebindToTask(Task t) {
         mTask = t;
@@ -236,9 +245,6 @@
         mApplicationIcon.setImageDrawable(null);
         mApplicationIcon.setOnClickListener(null);
         mMoveTaskButton.setOnClickListener(null);
-
-        // Stop any focus animations
-        Utilities.cancelAnimationWithoutCallbacks(mFocusAnimator);
     }
 
     /** Updates the resize task bar button. */
@@ -332,39 +338,9 @@
     protected void dispatchDraw(Canvas canvas) {
         super.dispatchDraw(canvas);
 
-        // Draw the thumbnail with the rounded corners
-        canvas.drawRoundRect(0, 0, getWidth(), getHeight(),
-                mCornerRadius,
-                mCornerRadius, mDimLayerPaint);
-    }
-
-    /** Notifies the associated TaskView has been focused. */
-    void onTaskViewFocusChanged(boolean focused, boolean animateFocusedState) {
-        boolean isRunning = false;
-        if (mFocusAnimator != null) {
-            isRunning = mFocusAnimator.isRunning();
-        }
-        Utilities.cancelAnimationWithoutCallbacks(mFocusAnimator);
-
-        if (focused) {
-            if (animateFocusedState) {
-                // Bump up the translation
-                mFocusAnimator = ObjectAnimator.ofFloat(this, "translationZ", FOCUS_TRANSLATION_Z);
-                mFocusAnimator.setDuration(200);
-                mFocusAnimator.start();
-            } else {
-                setTranslationZ(FOCUS_TRANSLATION_Z);
-            }
-        } else {
-            if (isRunning) {
-                // Restore the translation
-                mFocusAnimator = ObjectAnimator.ofFloat(this, "translationZ", 0f);
-                mFocusAnimator.setDuration(150);
-                mFocusAnimator.start();
-            } else {
-                setTranslationZ(0f);
-            }
-        }
+        // Draw the dim layer with the rounded corners
+        canvas.drawRoundRect(0, 0, mTaskViewRect.width(), getHeight(),
+                mCornerRadius, mCornerRadius, mDimLayerPaint);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
index 7bb2c7b..37d8cd6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
@@ -56,6 +56,7 @@
             };
 
     // Drawing
+    Rect mTaskViewRect = new Rect();
     int mCornerRadius;
     float mDimAlpha;
     Matrix mScaleMatrix = new Matrix();
@@ -98,13 +99,22 @@
                 com.android.internal.R.interpolator.fast_out_slow_in);
     }
 
+    /**
+     * Called when the task view frame changes, allowing us to move the contents of the header
+     * to match the frame changes.
+     */
+    public void onTaskViewSizeChanged(int width, int height) {
+        mTaskViewRect.set(0, 0, width, height);
+        invalidate();
+    }
+
     @Override
     protected void onDraw(Canvas canvas) {
         if (mInvisible) {
             return;
         }
         // Draw the thumbnail with the rounded corners
-        canvas.drawRoundRect(0, 0, getWidth(), getHeight(),
+        canvas.drawRoundRect(0, 0, mTaskViewRect.width(), mTaskViewRect.height(),
                 mCornerRadius,
                 mCornerRadius, mDrawPaint);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
index c3e0906..3ee50ac 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
@@ -18,6 +18,9 @@
 
 import android.animation.ValueAnimator;
 import android.graphics.RectF;
+import android.util.IntProperty;
+import android.util.Property;
+import android.view.View;
 import android.view.ViewPropertyAnimator;
 import android.view.animation.Interpolator;
 
@@ -25,26 +28,70 @@
 /* The transform state for a task view */
 public class TaskViewTransform {
 
+    public static final Property<View, Integer> LEFT =
+            new IntProperty<View>("left") {
+                @Override
+                public void setValue(View object, int v) {
+                    object.setLeft(v);
+                }
+
+                @Override
+                public Integer get(View object) {
+                    return object.getLeft();
+                }
+            };
+
+    public static final Property<View, Integer> TOP =
+            new IntProperty<View>("top") {
+                @Override
+                public void setValue(View object, int v) {
+                    object.setTop(v);
+                }
+
+                @Override
+                public Integer get(View object) {
+                    return object.getTop();
+                }
+            };
+
+    public static final Property<View, Integer> RIGHT =
+            new IntProperty<View>("right") {
+                @Override
+                public void setValue(View object, int v) {
+                    object.setRight(v);
+                }
+
+                @Override
+                public Integer get(View object) {
+                    return object.getRight();
+                }
+            };
+
+    public static final Property<View, Integer> BOTTOM =
+            new IntProperty<View>("bottom") {
+                @Override
+                public void setValue(View object, int v) {
+                    object.setBottom(v);
+                }
+
+                @Override
+                public Integer get(View object) {
+                    return object.getBottom();
+                }
+            };
+
     // TODO: Move this out of the transform
     public int startDelay = 0;
 
-    public int translationX = 0;
-    public int translationY = 0;
     public float translationZ = 0;
     public float scale = 1f;
     public float alpha = 1f;
-
-    // Clip and thumbnail scale are untransformed layout-space properties
-    // The bottom clip is only used for freeform workspace tasks
-    public int clipBottom = 0;
-    public int clipRight = 0;
     public float thumbnailScale = 1f;
 
     public boolean visible = false;
     float p = 0f;
 
-    // This is a window-space rect that is purely used for coordinating the animation of an app
-    // window into Recents.
+    // This is a window-space rect used for positioning the task in the stack and freeform workspace
     public RectF rect = new RectF();
 
     public TaskViewTransform() {
@@ -56,13 +103,9 @@
      */
     public void reset() {
         startDelay = 0;
-        translationX = 0;
-        translationY = 0;
         translationZ = 0;
         scale = 1f;
         alpha = 1f;
-        clipBottom = 0;
-        clipRight = 0;
         thumbnailScale = 1f;
         visible = false;
         rect.setEmpty();
@@ -76,12 +119,6 @@
     public boolean hasScaleChangedFrom(float v) {
         return (Float.compare(scale, v) != 0);
     }
-    public boolean hasTranslationXChangedFrom(float v) {
-        return (Float.compare(translationX, v) != 0);
-    }
-    public boolean hasTranslationYChangedFrom(float v) {
-        return (Float.compare(translationY, v) != 0);
-    }
     public boolean hasTranslationZChangedFrom(float v) {
         return (Float.compare(translationZ, v) != 0);
     }
@@ -95,12 +132,6 @@
             boolean requiresLayers = false;
 
             // Animate to the final state
-            if (hasTranslationXChangedFrom(v.getTranslationX())) {
-                anim.translationX(translationX);
-            }
-            if (hasTranslationYChangedFrom(v.getTranslationY())) {
-                anim.translationY(translationY);
-            }
             if (allowShadows && hasTranslationZChangedFrom(v.getTranslationZ())) {
                 anim.translationZ(translationZ);
             }
@@ -129,12 +160,6 @@
                     .start();
         } else {
             // Set the changed properties
-            if (hasTranslationXChangedFrom(v.getTranslationX())) {
-                v.setTranslationX(translationX);
-            }
-            if (hasTranslationYChangedFrom(v.getTranslationY())) {
-                v.setTranslationY(translationY);
-            }
             if (allowShadows && hasTranslationZChangedFrom(v.getTranslationZ())) {
                 v.setTranslationZ(translationZ);
             }
@@ -150,7 +175,8 @@
 
     /** Reset the transform on a view. */
     public static void reset(TaskView v) {
-        // Cancel any running animations
+        // Cancel any running animations and reset the translation in case something else (like a
+        // dismiss animation) changes it
         v.animate().cancel();
         v.setTranslationX(0f);
         v.setTranslationY(0f);
@@ -158,16 +184,15 @@
         v.setScaleX(1f);
         v.setScaleY(1f);
         v.setAlpha(1f);
-        v.getViewBounds().setClipRight(0, false /* forceUpdate */);
         v.getViewBounds().setClipBottom(0, false /* forceUpdate */);
+        v.setLeftTopRightBottom(0, 0, 0, 0);
         v.mThumbnailView.setBitmapScale(1f);
     }
 
     @Override
     public String toString() {
-        return "TaskViewTransform delay: " + startDelay +
-                " x: " + translationX + " y: " + translationY + " z: " + translationZ +
-                " scale: " + scale + " alpha: " + alpha + " visible: " + visible + " rect: " + rect +
-                " p: " + p;
+        return "TaskViewTransform delay: " + startDelay + " z: " + translationZ +
+                " scale: " + scale + " alpha: " + alpha + " visible: " + visible +
+                " rect: " + rect + " p: " + p;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
index 58de5d5..ef47d8d 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
@@ -62,7 +62,7 @@
         @Override
         public void run() {
             try {
-                ActivityManagerNative.getDefault().removeStack(DOCKED_STACK_ID);
+                ActivityManagerNative.getDefault().moveTasksToFullscreenStack(DOCKED_STACK_ID);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed to remove stack: " + e);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 4714653..8b94e54 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -129,8 +129,8 @@
 
     public static final boolean ENABLE_REMOTE_INPUT =
             SystemProperties.getBoolean("debug.enable_remote_input", true);
-    public static final boolean ENABLE_CHILD_NOTIFICATIONS = Build.IS_DEBUGGABLE
-                    && SystemProperties.getBoolean("debug.child_notifs", false);
+    public static final boolean ENABLE_CHILD_NOTIFICATIONS
+            = SystemProperties.getBoolean("debug.child_notifs", true);
 
     protected static final int MSG_SHOW_RECENT_APPS = 1019;
     protected static final int MSG_HIDE_RECENT_APPS = 1020;
@@ -1301,7 +1301,6 @@
             // Since the number of notifications is determined based on the height of the view, we
             // need to update them.
             updateRowStates();
-            mStackScroller.onHeightChanged(null, false);
         }
     }
 
@@ -1546,7 +1545,6 @@
             }
         }
         entry.row = row;
-        updateNotificationHeightRange(entry);
         entry.row.setOnActivatedListener(this);
         entry.row.setExpandable(bigContentViewLocal != null);
 
@@ -1559,19 +1557,11 @@
             row.setUserExpanded(userExpanded);
         }
         row.setUserLocked(userLocked);
-        row.updateStatusBarNotification(entry.notification);
+        row.onNotificationUpdated(entry);
         applyRemoteInput(entry);
         return true;
     }
 
-    private void updateNotificationHeightRange(Entry entry) {
-        boolean customView = entry.getContentView().getId()
-                != com.android.internal.R.id.status_bar_latest_event_content;
-        boolean beforeN = entry.targetSdk < Build.VERSION_CODES.N;
-        int minHeight = customView && beforeN ? mRowMinHeightLegacy : mRowMinHeight;
-        entry.row.setHeightRange(minHeight, mRowMaxHeight);
-    }
-
     /**
      * Adds RemoteInput actions from the WearableExtender; to be removed once more apps support this
      * via first-class API.
@@ -1614,7 +1604,7 @@
     private void applyRemoteInput(final Entry entry) {
         if (!ENABLE_REMOTE_INPUT) return;
 
-        RemoteInput remoteInput = null;
+        boolean hasRemoteInput = false;
 
         Notification.Action[] actions = entry.notification.getNotification().actions;
         if (actions != null) {
@@ -1622,7 +1612,7 @@
                 if (a.getRemoteInputs() != null) {
                     for (RemoteInput ri : a.getRemoteInputs()) {
                         if (ri.getAllowFreeFormInput()) {
-                            remoteInput = ri;
+                            hasRemoteInput = true;
                             break;
                         }
                     }
@@ -1630,34 +1620,50 @@
             }
         }
 
-        // See if we have somewhere to put that remote input
-        if (remoteInput != null) {
-            View bigContentView = entry.getExpandedContentView();
-            if (bigContentView != null) {
-                inflateRemoteInput(bigContentView, entry);
-            }
-            View headsUpContentView = entry.getHeadsUpContentView();
-            if (headsUpContentView != null) {
-                inflateRemoteInput(headsUpContentView, entry);
-            }
+        View bigContentView = entry.getExpandedContentView();
+        if (bigContentView != null) {
+            applyRemoteInput(bigContentView, entry, hasRemoteInput);
+        }
+        View headsUpContentView = entry.getHeadsUpContentView();
+        if (headsUpContentView != null) {
+            applyRemoteInput(headsUpContentView, entry, hasRemoteInput);
         }
 
     }
 
-    private RemoteInputView inflateRemoteInput(View view, Entry entry) {
+    private RemoteInputView applyRemoteInput(View view, Entry entry, boolean hasRemoteInput) {
         View actionContainerCandidate = view.findViewById(
                 com.android.internal.R.id.actions_container);
         if (actionContainerCandidate instanceof FrameLayout) {
-            ViewGroup actionContainer = (FrameLayout) actionContainerCandidate;
-            RemoteInputView riv = inflateRemoteInputView(actionContainer, entry);
-            if (riv != null) {
-                riv.setVisibility(View.INVISIBLE);
-                actionContainer.addView(riv, new FrameLayout.LayoutParams(
-                        ViewGroup.LayoutParams.MATCH_PARENT,
-                        ViewGroup.LayoutParams.MATCH_PARENT)
-                );
-                riv.setBackgroundColor(entry.notification.getNotification().color);
-                return riv;
+            RemoteInputView existing = (RemoteInputView)
+                    view.findViewWithTag(RemoteInputView.VIEW_TAG);
+
+            if (hasRemoteInput) {
+                if (existing != null) {
+                    existing.onNotificationUpdate();
+                    return existing;
+                }
+
+                ViewGroup actionContainer = (FrameLayout) actionContainerCandidate;
+                RemoteInputView riv = inflateRemoteInputView(actionContainer, entry);
+                if (riv != null) {
+                    riv.setVisibility(View.INVISIBLE);
+                    actionContainer.addView(riv, new FrameLayout.LayoutParams(
+                            ViewGroup.LayoutParams.MATCH_PARENT,
+                            ViewGroup.LayoutParams.MATCH_PARENT)
+                    );
+                    int color = entry.notification.getNotification().color;
+                    if (color == Notification.COLOR_DEFAULT) {
+                        color = mContext.getColor(R.color.default_remote_input_background);
+                    }
+                    riv.setBackgroundColor(color);
+                    return riv;
+                }
+            } else {
+                if (existing != null) {
+                    existing.onNotificationUpdate();
+                    return null;
+                }
             }
         }
         return null;
@@ -2193,7 +2199,7 @@
         // update the contentIntent
         mNotificationClicker.register(entry.row, sbn);
 
-        entry.row.updateStatusBarNotification(entry.notification);
+        entry.row.onNotificationUpdated(entry);
         entry.row.resetHeight();
 
         applyRemoteInput(entry);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 7a94a58..bd143ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -22,6 +22,7 @@
 import android.graphics.drawable.AnimationDrawable;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.service.notification.StatusBarNotification;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
@@ -49,6 +50,11 @@
     private static final int DEFAULT_DIVIDER_ALPHA = 0x29;
     private static final int COLORED_DIVIDER_ALPHA = 0x7B;
     private final LinearInterpolator mLinearInterpolator = new LinearInterpolator();
+    private final int mNotificationMinHeightLegacy;
+    private final int mMaxHeadsUpHeightLegacy;
+    private final int mMaxHeadsUpHeight;
+    private final int mNotificationMinHeight;
+    private final int mNotificationMaxHeight;
     private int mRowMinHeight;
 
     /** Does this row contain layouts that can adapt to row expansion */
@@ -86,10 +92,12 @@
     private String mLoggingKey;
     private boolean mWasReset;
     private NotificationGuts mGuts;
+    private NotificationData.Entry mEntry;
     private StatusBarNotification mStatusBarNotification;
     private boolean mIsHeadsUp;
     private boolean mLastChronometerRunning = true;
     private NotificationHeaderView mNotificationHeader;
+    private NotificationViewWrapper mNotificationHeaderWrapper;
     private ViewStub mChildrenContainerStub;
     private NotificationGroupManager mGroupManager;
     private boolean mChildrenExpanded;
@@ -99,6 +107,7 @@
     private boolean mIsSystemChildExpanded;
     private boolean mIsPinned;
     private FalsingManager mFalsingManager;
+    private NotificationHeaderUtil mHeaderUtil = new NotificationHeaderUtil(this);
 
     private boolean mJustClicked;
     private boolean mIconAnimationRunning;
@@ -187,10 +196,11 @@
         }
     }
 
-    public void updateStatusBarNotification(StatusBarNotification statusBarNotification) {
-        mStatusBarNotification = statusBarNotification;
-        mPrivateLayout.onNotificationUpdated(statusBarNotification);
-        mPublicLayout.onNotificationUpdated(statusBarNotification);
+    public void onNotificationUpdated(NotificationData.Entry entry) {
+        mEntry = entry;
+        mStatusBarNotification = entry.notification;
+        mPrivateLayout.onNotificationUpdated(entry.notification);
+        mPublicLayout.onNotificationUpdated(entry.notification);
         updateVetoButton();
         if (mIsSummaryWithChildren) {
             recreateNotificationHeader();
@@ -198,7 +208,28 @@
         if (mIconAnimationRunning) {
             setIconAnimationRunning(true);
         }
+        if (mNotificationParent != null) {
+            mNotificationParent.updateChildrenHeaderAppearance();
+        }
         onChildrenCountChanged();
+        updateLimits();
+    }
+
+    private void updateLimits() {
+        boolean customView = getPrivateLayout().getContractedChild().getId()
+                != com.android.internal.R.id.status_bar_latest_event_content;
+        boolean beforeN = mEntry.targetSdk < Build.VERSION_CODES.N;
+        int minHeight = customView && beforeN && !mIsSummaryWithChildren ?
+                mNotificationMinHeightLegacy : mNotificationMinHeight;
+        boolean headsUpCustom = getPrivateLayout().getHeadsUpChild() != null &&
+                getPrivateLayout().getHeadsUpChild().getId()
+                != com.android.internal.R.id.status_bar_latest_event_content;
+        int headsUpheight = headsUpCustom && beforeN ? mMaxHeadsUpHeightLegacy
+                : mMaxHeadsUpHeight;
+        mRowMinHeight = minHeight;
+        mMaxViewHeight = mNotificationMaxHeight;
+        mPrivateLayout.setHeights(mRowMinHeight, headsUpheight);
+        mPublicLayout.setHeights(mRowMinHeight, headsUpheight);
     }
 
     public StatusBarNotification getStatusBarNotification() {
@@ -246,6 +277,7 @@
         if (mChildrenContainer != null) {
             mChildrenContainer.removeNotification(row);
         }
+        mHeaderUtil.restoreNotificationHeader(row);
         onChildrenCountChanged();
         row.setIsChildInGroup(false, null);
     }
@@ -361,6 +393,9 @@
     }
 
     public int getHeadsUpHeight() {
+        if (mIsSummaryWithChildren) {
+            return mChildrenContainer.getIntrinsicHeight();
+        }
         return mHeadsUpHeight;
     }
 
@@ -414,17 +449,11 @@
         }
     }
 
-    public CharSequence getSubText() {
-        Notification notification = mStatusBarNotification.getNotification();
-        CharSequence subText = notification.extras.getCharSequence(Notification.EXTRA_SUMMARY_TEXT);
-        if (subText == null) {
-            subText = notification.extras.getCharSequence(Notification.EXTRA_SUB_TEXT);
+    public NotificationHeaderView getNotificationHeader() {
+        if (mNotificationHeader != null) {
+            return mNotificationHeader;
         }
-        return subText;
-    }
-
-    public void setContentSubTextVisible(boolean visible) {
-        mPrivateLayout.setSubTextVisible(visible);
+        return mPrivateLayout.getNotificationHeader();
     }
 
     public void setOnExpandClickListener(OnExpandClickListener onExpandClickListener) {
@@ -438,6 +467,16 @@
     public ExpandableNotificationRow(Context context, AttributeSet attrs) {
         super(context, attrs);
         mFalsingManager = FalsingManager.getInstance(context);
+        mNotificationMinHeightLegacy =  getResources().getDimensionPixelSize(
+                R.dimen.notification_min_height_legacy);
+        mNotificationMinHeight =  getResources().getDimensionPixelSize(
+                R.dimen.notification_min_height);
+        mNotificationMaxHeight =  getResources().getDimensionPixelSize(
+                R.dimen.notification_max_height);
+        mMaxHeadsUpHeightLegacy =  getResources().getDimensionPixelSize(
+                R.dimen.notification_max_heads_up_height_legacy);
+        mMaxHeadsUpHeight =  getResources().getDimensionPixelSize(
+                R.dimen.notification_max_heads_up_height);
     }
 
     /**
@@ -514,13 +553,15 @@
         }
     }
 
-    private void updateChildrenVisibility(boolean animated) {
+    private void updateChildrenVisibility() {
         if (mChildrenContainer == null) {
             return;
         }
         mChildrenContainer.setVisibility(mIsSummaryWithChildren ? VISIBLE : INVISIBLE);
         mNotificationHeader.setVisibility(mIsSummaryWithChildren ? VISIBLE : INVISIBLE);
         mPrivateLayout.setVisibility(!mIsSummaryWithChildren ? VISIBLE : INVISIBLE);
+        // The limits might have changed if the view suddenly became a group or vice versa
+        updateLimits();
     }
 
     @Override
@@ -544,13 +585,10 @@
         if (showing != null) {
             showing.setDark(dark, fade, delay);
         }
-    }
-
-    public void setHeightRange(int rowMinHeight, int rowMaxHeight) {
-        mRowMinHeight = rowMinHeight;
-        mMaxViewHeight = rowMaxHeight;
-        mPrivateLayout.setSmallHeight(mRowMinHeight);
-        mPublicLayout.setSmallHeight(mRowMinHeight);
+        if (mIsSummaryWithChildren) {
+            mChildrenContainer.setDark(dark, fade, delay);
+            mNotificationHeaderWrapper.setDark(dark, fade, delay);
+        }
     }
 
     public boolean isExpandable() {
@@ -650,6 +688,9 @@
             mOnKeyguard = onKeyguard;
             logExpansionEvent(false, wasExpanded);
             if (wasExpanded != isExpanded()) {
+                if (mIsSummaryWithChildren) {
+                    mChildrenContainer.updateGroupOverflow();
+                }
                 notifyHeightChanged(false  /* needsAnimation */);
             }
         }
@@ -720,8 +761,9 @@
             }
         }
         mPrivateLayout.updateExpandButtons(isExpandable());
+        updateChildrenHeaderAppearance();
         updateHeaderChildCount();
-        updateChildrenVisibility(true);
+        updateChildrenVisibility();
     }
 
     /**
@@ -841,6 +883,9 @@
 
     public void setChildrenExpanded(boolean expanded, boolean animate) {
         mChildrenExpanded = expanded;
+        if (mNotificationHeader != null) {
+            mNotificationHeader.setExpanded(expanded);
+        }
         if (mChildrenContainer != null) {
             mChildrenContainer.setChildrenExpanded(expanded);
         }
@@ -944,13 +989,30 @@
                     com.android.internal.R.id.expand_button);
             expandButton.setVisibility(VISIBLE);
             mNotificationHeader.setOnClickListener(mExpandClickListener);
+            mNotificationHeaderWrapper = NotificationViewWrapper.wrap(getContext(),
+                    mNotificationHeader);
             addView(mNotificationHeader);
         } else {
             header.reapply(getContext(), mNotificationHeader);
+            mNotificationHeaderWrapper.notifyContentUpdated();
         }
+        updateHeaderExpandButton();
+        updateChildrenHeaderAppearance();
         updateHeaderChildCount();
     }
 
+    private void updateHeaderExpandButton() {
+        if (mIsSummaryWithChildren) {
+            mNotificationHeader.setIsGroupHeader(true /* isGroupHeader*/);
+        }
+    }
+
+    public void updateChildrenHeaderAppearance() {
+        if (mIsSummaryWithChildren) {
+            mHeaderUtil.updateChildrenHeaderAppearance();
+        }
+    }
+
     public boolean isMaxExpandHeightInitialized() {
         return mMaxExpandHeight != 0;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index fb8086c..2944c4f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -52,8 +52,6 @@
     private static final int VISIBLE_TYPE_SINGLELINE = 3;
 
     private final Rect mClipBounds = new Rect();
-    private final int mSingleLineHeight;
-    private final int mHeadsUpHeight;
     private final int mRoundRectRadius;
     private final Interpolator mLinearInterpolator = new LinearInterpolator();
     private final boolean mRoundRectClippingEnabled;
@@ -78,6 +76,7 @@
     private boolean mShowingLegacyBackground;
     private boolean mIsChildInGroup;
     private int mSmallHeight;
+    private int mHeadsUpHeight;
     private StatusBarNotification mStatusBarNotification;
     private NotificationGroupManager mGroupManager;
 
@@ -104,9 +103,6 @@
         super(context, attrs);
         mHybridViewManager = new HybridNotificationViewManager(getContext(), this);
         mFadePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.ADD));
-        mSingleLineHeight = getResources().getDimensionPixelSize(
-                R.dimen.notification_single_line_height);
-        mHeadsUpHeight = getResources().getDimensionPixelSize(R.dimen.notification_mid_height);
         mRoundRectRadius = getResources().getDimensionPixelSize(
                 R.dimen.notification_material_rounded_rect_radius);
         mRoundRectClippingEnabled = getResources().getBoolean(
@@ -115,8 +111,9 @@
         setOutlineProvider(mOutlineProvider);
     }
 
-    public void setSmallHeight(int smallHeight) {
+    public void setHeights(int smallHeight, int headsUpMaxHeight) {
         mSmallHeight = smallHeight;
+        mHeadsUpHeight = headsUpMaxHeight;
     }
 
     @Override
@@ -153,16 +150,15 @@
             ViewGroup.LayoutParams layoutParams = mHeadsUpChild.getLayoutParams();
             if (layoutParams.height >= 0) {
                 // An actual height is set
-                size = Math.min(maxSize, layoutParams.height);
+                size = Math.min(size, layoutParams.height);
             }
             mHeadsUpChild.measure(widthMeasureSpec,
                     MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST));
             maxChildHeight = Math.max(maxChildHeight, mHeadsUpChild.getMeasuredHeight());
         }
         if (mSingleLineView != null) {
-            int size = Math.min(maxSize, mSingleLineHeight);
             mSingleLineView.measure(widthMeasureSpec,
-                    MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY));
+                    MeasureSpec.makeMeasureSpec(maxSize, MeasureSpec.AT_MOST));
             maxChildHeight = Math.max(maxChildHeight, mSingleLineView.getMeasuredHeight());
         }
         int ownHeight = Math.min(maxChildHeight, maxSize);
@@ -287,17 +283,17 @@
     }
 
     public int getMaxHeight() {
-        if (mIsHeadsUp && mHeadsUpChild != null) {
-            return mHeadsUpChild.getHeight();
-        } else if (mExpandedChild != null) {
+        if (mExpandedChild != null) {
             return mExpandedChild.getHeight();
+        } else if (mIsHeadsUp && mHeadsUpChild != null) {
+            return mHeadsUpChild.getHeight();
         }
         return mSmallHeight;
     }
 
     public int getMinHeight() {
         if (mIsChildInGroup && !isGroupExpanded()) {
-            return mSingleLineHeight;
+            return mSingleLineView.getHeight();
         } else {
             return mSmallHeight;
         }
@@ -461,6 +457,9 @@
         if (mDark == dark || mContractedChild == null) return;
         mDark = dark;
         mContractedWrapper.setDark(dark && !mShowingLegacyBackground, fade, delay);
+        if (mSingleLineView != null) {
+            mSingleLineView.setDark(dark, fade, delay);
+        }
     }
 
     public void setHeadsUp(boolean headsUp) {
@@ -509,18 +508,6 @@
         }
     }
 
-    public void setSubTextVisible(boolean visible) {
-        if (mExpandedChild != null) {
-            mExpandedWrapper.setSubTextVisible(visible);
-        }
-        if (mContractedChild != null) {
-            mContractedWrapper.setSubTextVisible(visible);
-        }
-        if (mHeadsUpChild != null) {
-            mHeadsUpWrapper.setSubTextVisible(visible);
-        }
-    }
-
     public void setGroupManager(NotificationGroupManager groupManager) {
         mGroupManager = groupManager;
     }
@@ -540,4 +527,18 @@
             mHeadsUpWrapper.updateExpandability(expandable,  mExpandClickListener);
         }
     }
+
+    public NotificationHeaderView getNotificationHeader() {
+        NotificationHeaderView header = null;
+        if (mContractedChild != null) {
+            header = mContractedWrapper.getNotificationHeader();
+        }
+        if (header == null && mExpandedChild != null) {
+            header = mExpandedWrapper.getNotificationHeader();
+        }
+        if (header == null && mHeadsUpChild != null) {
+            header = mHeadsUpWrapper.getNotificationHeader();
+        }
+        return header;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
new file mode 100644
index 0000000..859a330
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
@@ -0,0 +1,346 @@
+/*
+ * 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;
+
+import android.app.Notification;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Icon;
+import android.text.TextUtils;
+import android.view.NotificationHeaderView;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * A Util to manage {@link android.view.NotificationHeaderView} objects and their redundancies.
+ */
+public class NotificationHeaderUtil {
+
+    private static final TextViewComparator sTextViewComparator = new TextViewComparator();
+    private static final VisibilityApplicator sVisibilityApplicator = new VisibilityApplicator();
+    private static  final DataExtractor sIconExtractor = new DataExtractor() {
+        @Override
+        public Object extractData(ExpandableNotificationRow row) {
+            return row.getStatusBarNotification().getNotification();
+        }
+    };
+    private static final IconComparator sIconVisibilityComparator = new IconComparator() {
+        public boolean compare(View parent, View child, Object parentData,
+                Object childData) {
+            return hasSameIcon(parentData, childData)
+                    && hasSameColor(parentData, childData);
+        }
+    };
+    private static final IconComparator sGreyComparator = new IconComparator() {
+        public boolean compare(View parent, View child, Object parentData,
+                Object childData) {
+            return !hasSameIcon(parentData, childData)
+                    || hasSameColor(parentData, childData);
+        }
+    };
+    private final static ResultApplicator mGreyApplicator = new ResultApplicator() {
+        @Override
+        public void apply(View view, boolean apply) {
+            NotificationHeaderView header = (NotificationHeaderView) view;
+            ImageView icon = (ImageView) view.findViewById(
+                    com.android.internal.R.id.icon);
+            ImageView expand = (ImageView) view.findViewById(
+                    com.android.internal.R.id.expand_button);
+            applyToChild(icon, apply, header.getOriginalIconColor());
+            int color = header.getOriginalNotificationColor();
+            if (color == Notification.COLOR_DEFAULT) {
+                color = view.getContext().getColor(
+                        com.android.internal.R.color.notification_icon_default_color);
+            }
+            applyToChild(expand, apply, color);
+        }
+
+        private void applyToChild(View view, boolean shouldApply, int originalColor) {
+            if (view.getVisibility() == View.VISIBLE
+                    && originalColor != NotificationHeaderView.NO_COLOR) {
+                ImageView imageView = (ImageView) view;
+                imageView.getDrawable().mutate();
+                if (shouldApply) {
+                    // lets gray it out
+                    int grey = view.getContext().getColor(
+                            com.android.internal.R.color.notification_icon_default_color);
+                    imageView.getDrawable().setColorFilter(grey, PorterDuff.Mode.SRC_ATOP);
+                } else {
+                    // lets reset it
+                    imageView.getDrawable().setColorFilter(originalColor,
+                            PorterDuff.Mode.SRC_ATOP);
+                }
+            }
+        }
+    };
+
+    private final ExpandableNotificationRow mRow;
+    private final ArrayList<HeaderProcessor> mComparators = new ArrayList<>();
+    private final HashSet<Integer> mDividers = new HashSet<>();
+
+    NotificationHeaderUtil(ExpandableNotificationRow row) {
+        mRow = row;
+        // To hide the icons if they are the same and the color is the same
+        mComparators.add(new HeaderProcessor(mRow,
+                com.android.internal.R.id.icon,
+                sIconExtractor,
+                sIconVisibilityComparator,
+                sVisibilityApplicator));
+        // To grey them out the icons and expand button when the icons are not the same
+        mComparators.add(new HeaderProcessor(mRow,
+                com.android.internal.R.id.notification_header,
+                sIconExtractor,
+                sGreyComparator,
+                mGreyApplicator));
+        mComparators.add(HeaderProcessor.forTextView(mRow,
+                com.android.internal.R.id.app_name_text));
+        mComparators.add(HeaderProcessor.forTextView(mRow,
+                com.android.internal.R.id.header_sub_text));
+        mComparators.add(HeaderProcessor.forTextView(mRow,
+                com.android.internal.R.id.header_content_info));
+        mDividers.add(com.android.internal.R.id.sub_text_divider);
+        mDividers.add(com.android.internal.R.id.content_info_divider);
+        mDividers.add(com.android.internal.R.id.time_divider);
+    }
+
+    public void updateChildrenHeaderAppearance() {
+        List<ExpandableNotificationRow> notificationChildren = mRow.getNotificationChildren();
+        if (notificationChildren == null) {
+            return;
+        }
+        // Initialize the comparators
+        for (int compI = 0; compI < mComparators.size(); compI++) {
+            mComparators.get(compI).init();
+        }
+
+        // Compare all notification headers
+        for (int i = 0; i < notificationChildren.size(); i++) {
+            ExpandableNotificationRow row = notificationChildren.get(i);
+            for (int compI = 0; compI < mComparators.size(); compI++) {
+                mComparators.get(compI).compareToHeader(row);
+            }
+        }
+
+        // Apply the comparison to the row
+        for (int i = 0; i < notificationChildren.size(); i++) {
+            ExpandableNotificationRow row = notificationChildren.get(i);
+            for (int compI = 0; compI < mComparators.size(); compI++) {
+                mComparators.get(compI).apply(row);
+            }
+            // We need to sanitize the dividers since they might be off-balance now
+            sanitizeDividers(row);
+        }
+    }
+
+    private void sanitizeDividers(ExpandableNotificationRow row) {
+        if (row.isSummaryWithChildren()) {
+            sanitizeHeader(row.getNotificationHeader());
+            return;
+        }
+        final NotificationContentView layout = row.getPrivateLayout();
+        sanitizeChild(layout.getContractedChild());
+        sanitizeChild(layout.getHeadsUpChild());
+        sanitizeChild(layout.getExpandedChild());
+    }
+
+    private void sanitizeChild(View child) {
+        if (child != null) {
+            NotificationHeaderView header = (NotificationHeaderView) child.findViewById(
+                    com.android.internal.R.id.notification_header);
+            sanitizeHeader(header);
+        }
+    }
+
+    private void sanitizeHeader(NotificationHeaderView rowHeader) {
+        if (rowHeader == null) {
+            return;
+        }
+        View left = null;
+        View right;
+        final int childCount = rowHeader.getChildCount();
+        for (int i = 1; i < childCount - 1 ; i++) {
+            View child = rowHeader.getChildAt(i);
+            if (mDividers.contains(Integer.valueOf(child.getId()))) {
+                boolean visible = false;
+                // Lets find the item to the right
+                for (i++; i < childCount - 1; i++) {
+                    right = rowHeader.getChildAt(i);
+                    if (mDividers.contains(Integer.valueOf(right.getId()))) {
+                        // A divider was found, this needs to be hidden
+                        i--;
+                        break;
+                    } else if (right.getVisibility() == View.VISIBLE) {
+                        visible = left != null;
+                        left = right;
+                        break;
+                    }
+                }
+                child.setVisibility(visible ? View.VISIBLE : View.GONE);
+            } else if (child.getVisibility() == View.VISIBLE) {
+                left = child;
+            }
+        }
+    }
+
+    public void restoreNotificationHeader(ExpandableNotificationRow row) {
+        for (int compI = 0; compI < mComparators.size(); compI++) {
+            mComparators.get(compI).apply(row, true /* reset */);
+        }
+        sanitizeDividers(row);
+    }
+
+    private static class HeaderProcessor {
+        private final int mId;
+        private final DataExtractor mExtractor;
+        private final ResultApplicator mApplicator;
+        private final ExpandableNotificationRow mParentRow;
+        private boolean mApply;
+        private View mParentView;
+        private ViewComparator mComparator;
+        private Object mParentData;
+
+        public static HeaderProcessor forTextView(ExpandableNotificationRow row, int id) {
+            return new HeaderProcessor(row, id, null, sTextViewComparator, sVisibilityApplicator);
+        }
+
+        HeaderProcessor(ExpandableNotificationRow row, int id, DataExtractor extractor,
+                ViewComparator comparator,
+                ResultApplicator applicator) {
+            mId = id;
+            mExtractor = extractor;
+            mApplicator = applicator;
+            mComparator = comparator;
+            mParentRow = row;
+        }
+
+        public void init() {
+            mParentView = mParentRow.getNotificationHeader().findViewById(mId);
+            mParentData = mExtractor == null ? null : mExtractor.extractData(mParentRow);
+            mApply = !mComparator.isEmpty(mParentView);
+        }
+        public void compareToHeader(ExpandableNotificationRow row) {
+            if (!mApply) {
+                return;
+            }
+            NotificationHeaderView header = row.getNotificationHeader();
+            if (header == null) {
+                mApply = false;
+                return;
+            }
+            Object childData = mExtractor == null ? null : mExtractor.extractData(row);
+            mApply = mComparator.compare(mParentView, header.findViewById(mId),
+                    mParentData, childData);
+        }
+
+        public void apply(ExpandableNotificationRow row) {
+            apply(row, false /* reset */);
+        }
+
+        public void apply(ExpandableNotificationRow row, boolean reset) {
+            boolean apply = mApply && !reset;
+            if (row.isSummaryWithChildren()) {
+                applyToView(apply, row.getNotificationHeader());
+                return;
+            }
+            applyToView(apply, row.getPrivateLayout().getContractedChild());
+            applyToView(apply, row.getPrivateLayout().getHeadsUpChild());
+            applyToView(apply, row.getPrivateLayout().getExpandedChild());
+        }
+
+        private void applyToView(boolean apply, View parent) {
+            if (parent != null) {
+                View view = parent.findViewById(mId);
+                if (view != null && !mComparator.isEmpty(view)) {
+                    mApplicator.apply(view, apply);
+                }
+            }
+        }
+    }
+
+    private interface ViewComparator {
+        /**
+         * @param parent the parent view
+         * @param child the child view
+         * @param parentData optional data for the parent
+         * @param childData optional data for the child
+         * @return whether to views are the same
+         */
+        boolean compare(View parent, View child, Object parentData, Object childData);
+        boolean isEmpty(View view);
+    }
+
+    private interface DataExtractor {
+        Object extractData(ExpandableNotificationRow row);
+    }
+
+    private static class TextViewComparator implements ViewComparator {
+        @Override
+        public boolean compare(View parent, View child, Object parentData, Object childData) {
+            TextView parentView = (TextView) parent;
+            TextView childView = (TextView) child;
+            return parentView.getText().equals(childView.getText());
+        }
+
+        @Override
+        public boolean isEmpty(View view) {
+            return TextUtils.isEmpty(((TextView) view).getText());
+        }
+    }
+
+    private static abstract class IconComparator implements ViewComparator {
+        @Override
+        public boolean compare(View parent, View child, Object parentData, Object childData) {
+            return false;
+        }
+
+        protected boolean hasSameIcon(Object parentData, Object childData) {
+            Icon parentIcon = ((Notification) parentData).getSmallIcon();
+            Icon childIcon = ((Notification) childData).getSmallIcon();
+            return parentIcon.sameAs(childIcon);
+        }
+
+        /**
+         * @return whether two ImageViews have the same colorFilterSet or none at all
+         */
+        protected boolean hasSameColor(Object parentData, Object childData) {
+            int parentColor = ((Notification) parentData).color;
+            int childColor = ((Notification) childData).color;
+            return parentColor == childColor;
+        }
+
+        @Override
+        public boolean isEmpty(View view) {
+            return false;
+        }
+    }
+
+    private interface ResultApplicator {
+        void apply(View view, boolean apply);
+    }
+
+    private static class VisibilityApplicator implements ResultApplicator {
+
+        @Override
+        public void apply(View view, boolean apply) {
+            view.setVisibility(apply ? View.GONE : View.VISIBLE);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderViewWrapper.java
new file mode 100644
index 0000000..ddad2e0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderViewWrapper.java
@@ -0,0 +1,239 @@
+/*
+ * 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;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.drawable.Drawable;
+import android.view.NotificationHeaderView;
+import android.view.View;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+import android.widget.ImageView;
+
+import com.android.systemui.R;
+import com.android.systemui.ViewInvertHelper;
+import com.android.systemui.statusbar.phone.NotificationPanelView;
+
+import java.util.ArrayList;
+
+/**
+ * Wraps a notification header view.
+ */
+public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
+
+    private final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix();
+    private final PorterDuffColorFilter mIconColorFilter = new PorterDuffColorFilter(
+            0, PorterDuff.Mode.SRC_ATOP);
+    private final int mIconDarkAlpha;
+    private final int mIconDarkColor = 0xffffffff;
+    protected final Interpolator mLinearOutSlowInInterpolator;
+    protected final ViewInvertHelper mInvertHelper;
+
+    protected int mColor;
+    private ImageView mIcon;
+
+    private ImageView mExpandButton;
+    private NotificationHeaderView mNotificationHeader;
+
+    protected NotificationHeaderViewWrapper(Context ctx, View view) {
+        super(view);
+        mIconDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha);
+        mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(ctx,
+                android.R.interpolator.linear_out_slow_in);
+        mInvertHelper = new ViewInvertHelper(ctx, NotificationPanelView.DOZE_ANIMATION_DURATION);
+        resolveHeaderViews();
+    }
+
+    protected void resolveHeaderViews() {
+        mIcon = (ImageView) mView.findViewById(com.android.internal.R.id.icon);
+        mExpandButton = (ImageView) mView.findViewById(com.android.internal.R.id.expand_button);
+        mColor = resolveColor(mExpandButton);
+        mNotificationHeader = (NotificationHeaderView) mView.findViewById(
+                com.android.internal.R.id.notification_header);
+        for (int i = 0; i < mNotificationHeader.getChildCount(); i++) {
+            View child = mNotificationHeader.getChildAt(i);
+            if (child != mIcon) {
+                mInvertHelper.addTarget(child);
+            }
+        }
+    }
+
+    private int resolveColor(ImageView icon) {
+        if (icon != null && icon.getDrawable() != null) {
+            ColorFilter filter = icon.getDrawable().getColorFilter();
+            if (filter instanceof PorterDuffColorFilter) {
+                return ((PorterDuffColorFilter) filter).getColor();
+            }
+        }
+        return 0;
+    }
+
+    @Override
+    public void notifyContentUpdated() {
+        mInvertHelper.clearTargets();
+        // Reinspect the notification.
+        resolveHeaderViews();
+    }
+
+    @Override
+    public void setDark(boolean dark, boolean fade, long delay) {
+        if (fade) {
+            mInvertHelper.fade(dark, delay);
+        } else {
+            mInvertHelper.update(dark);
+        }
+        if (mIcon != null) {
+            boolean hadColorFilter = mNotificationHeader.getOriginalIconColor()
+                    != NotificationHeaderView.NO_COLOR;
+            if (fade) {
+                if (hadColorFilter) {
+                    fadeIconColorFilter(mIcon, dark, delay);
+                    fadeIconAlpha(mIcon, dark, delay);
+                } else {
+                    fadeGrayscale(mIcon, dark, delay);
+                }
+            } else {
+                if (hadColorFilter) {
+                    updateIconColorFilter(mIcon, dark);
+                    updateIconAlpha(mIcon, dark);
+                } else {
+                    updateGrayscale(mIcon, dark);
+                }
+            }
+        }
+    }
+
+    protected void startIntensityAnimation(ValueAnimator.AnimatorUpdateListener updateListener,
+            boolean dark, long delay, Animator.AnimatorListener listener) {
+        float startIntensity = dark ? 0f : 1f;
+        float endIntensity = dark ? 1f : 0f;
+        ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity);
+        animator.addUpdateListener(updateListener);
+        animator.setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION);
+        animator.setInterpolator(mLinearOutSlowInInterpolator);
+        animator.setStartDelay(delay);
+        if (listener != null) {
+            animator.addListener(listener);
+        }
+        animator.start();
+    }
+
+    private void fadeIconColorFilter(final ImageView target, boolean dark, long delay) {
+        startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                updateIconColorFilter(target, (Float) animation.getAnimatedValue());
+            }
+        }, dark, delay, null /* listener */);
+    }
+
+    private void fadeIconAlpha(final ImageView target, boolean dark, long delay) {
+        startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                float t = (float) animation.getAnimatedValue();
+                target.setImageAlpha((int) (255 * (1f - t) + mIconDarkAlpha * t));
+            }
+        }, dark, delay, null /* listener */);
+    }
+
+    protected void fadeGrayscale(final ImageView target, final boolean dark, long delay) {
+        startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                updateGrayscaleMatrix((float) animation.getAnimatedValue());
+                target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix));
+            }
+        }, dark, delay, new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                if (!dark) {
+                    target.setColorFilter(null);
+                }
+            }
+        });
+    }
+
+    private void updateIconColorFilter(ImageView target, boolean dark) {
+        updateIconColorFilter(target, dark ? 1f : 0f);
+    }
+
+    private void updateIconColorFilter(ImageView target, float intensity) {
+        int color = interpolateColor(mColor, mIconDarkColor, intensity);
+        mIconColorFilter.setColor(color);
+        Drawable iconDrawable = target.getDrawable();
+
+        // Also, the notification might have been modified during the animation, so background
+        // might be null here.
+        if (iconDrawable != null) {
+            iconDrawable.mutate().setColorFilter(mIconColorFilter);
+        }
+    }
+
+    private void updateIconAlpha(ImageView target, boolean dark) {
+        target.setImageAlpha(dark ? mIconDarkAlpha : 255);
+    }
+
+    protected void updateGrayscale(ImageView target, boolean dark) {
+        if (dark) {
+            updateGrayscaleMatrix(1f);
+            target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix));
+        } else {
+            target.setColorFilter(null);
+        }
+    }
+
+    @Override
+    public void updateExpandability(boolean expandable, View.OnClickListener onClickListener) {
+        mExpandButton.setVisibility(expandable ? View.VISIBLE : View.GONE);
+        mNotificationHeader.setOnClickListener(expandable ? onClickListener : null);
+    }
+
+    private void updateGrayscaleMatrix(float intensity) {
+        mGrayscaleColorMatrix.setSaturation(1 - intensity);
+    }
+
+    private static int interpolateColor(int source, int target, float t) {
+        int aSource = Color.alpha(source);
+        int rSource = Color.red(source);
+        int gSource = Color.green(source);
+        int bSource = Color.blue(source);
+        int aTarget = Color.alpha(target);
+        int rTarget = Color.red(target);
+        int gTarget = Color.green(target);
+        int bTarget = Color.blue(target);
+        return Color.argb(
+                (int) (aSource * (1f - t) + aTarget * t),
+                (int) (rSource * (1f - t) + rTarget * t),
+                (int) (gSource * (1f - t) + gTarget * t),
+                (int) (bSource * (1f - t) + bTarget * t));
+    }
+
+    @Override
+    public NotificationHeaderView getNotificationHeader() {
+        return mNotificationHeader;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java
index f20ccd5..77e8c55 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationTemplateViewWrapper.java
@@ -16,77 +16,31 @@
 
 package com.android.systemui.statusbar;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
 import android.content.Context;
-import android.content.res.ColorStateList;
 import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.ColorMatrix;
-import android.graphics.ColorMatrixColorFilter;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.text.TextUtils;
-import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
 import android.widget.ImageView;
 import android.widget.ProgressBar;
-import android.widget.TextView;
-
-import com.android.systemui.R;
-import com.android.systemui.ViewInvertHelper;
-import com.android.systemui.statusbar.phone.NotificationPanelView;
-
-import java.util.ArrayList;
 
 /**
  * Wraps a notification view inflated from a template.
  */
-public class NotificationTemplateViewWrapper extends NotificationViewWrapper {
+public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapper {
 
-    private final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix();
-    private final PorterDuffColorFilter mIconColorFilter = new PorterDuffColorFilter(
-            0, PorterDuff.Mode.SRC_ATOP);
-    private final int mIconDarkAlpha;
-    private final int mIconDarkColor = 0xffffffff;
-    private final int mDarkProgressTint = 0xffffffff;
-    private final Interpolator mLinearOutSlowInInterpolator;
+    private static final int mDarkProgressTint = 0xffffffff;
 
-    private int mColor;
-    private ViewInvertHelper mInvertHelper;
-    private ImageView mIcon;
     protected ImageView mPicture;
-
-    private TextView mSubText;
-    private View mSubTextDivider;
-    private ImageView mExpandButton;
-    private ViewGroup mNotificationHeader;
     private ProgressBar mProgressBar;
 
     protected NotificationTemplateViewWrapper(Context ctx, View view) {
-        super(view);
-        mIconDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha);
-        mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(ctx,
-                android.R.interpolator.linear_out_slow_in);
-
-        resolveViews();
+        super(ctx, view);
+        resolveTemplateViews();
     }
 
-    private void resolveViews() {
+    private void resolveTemplateViews() {
         View mainColumn = mView.findViewById(com.android.internal.R.id.notification_main_column);
-        mIcon = (ImageView) mView.findViewById(com.android.internal.R.id.icon);
         mPicture = (ImageView) mView.findViewById(com.android.internal.R.id.right_icon);
-        mSubText = (TextView) mView.findViewById(com.android.internal.R.id.header_sub_text);
-        mSubTextDivider = mView.findViewById(com.android.internal.R.id.sub_text_divider);
-        mExpandButton = (ImageView) mView.findViewById(com.android.internal.R.id.expand_button);
-        mColor = resolveColor(mExpandButton);
         final View progress = mView.findViewById(com.android.internal.R.id.progress);
         if (progress instanceof ProgressBar) {
             mProgressBar = (ProgressBar) progress;
@@ -94,30 +48,9 @@
             // It's still a viewstub
             mProgressBar = null;
         }
-        mNotificationHeader = (ViewGroup) mView.findViewById(
-                com.android.internal.R.id.notification_header);
-        ArrayList<View> viewsToInvert = new ArrayList<>();
         if (mainColumn != null) {
-            viewsToInvert.add(mainColumn);
+            mInvertHelper.addTarget(mainColumn);
         }
-        for (int i = 0; i < mNotificationHeader.getChildCount(); i++) {
-            View child = mNotificationHeader.getChildAt(i);
-            if (child != mIcon) {
-                viewsToInvert.add(child);
-            }
-        }
-        mInvertHelper = new ViewInvertHelper(viewsToInvert,
-                NotificationPanelView.DOZE_ANIMATION_DURATION);
-    }
-
-    private int resolveColor(ImageView icon) {
-        if (icon != null && icon.getDrawable() != null) {
-            ColorFilter filter = icon.getDrawable().getColorFilter();
-            if (filter instanceof PorterDuffColorFilter) {
-                return ((PorterDuffColorFilter) filter).getColor();
-            }
-        }
-        return 0;
     }
 
     @Override
@@ -125,27 +58,12 @@
         super.notifyContentUpdated();
 
         // Reinspect the notification.
-        resolveViews();
+        resolveTemplateViews();
     }
 
     @Override
     public void setDark(boolean dark, boolean fade, long delay) {
-        if (mInvertHelper != null) {
-            if (fade) {
-                mInvertHelper.fade(dark, delay);
-            } else {
-                mInvertHelper.update(dark);
-            }
-        }
-        if (mIcon != null) {
-            if (fade) {
-                fadeIconColorFilter(mIcon, dark, delay);
-                fadeIconAlpha(mIcon, dark, delay);
-            } else {
-                updateIconColorFilter(mIcon, dark);
-                updateIconAlpha(mIcon, dark);
-            }
-        }
+        super.setDark(dark, fade, delay);
         setPictureGrayscale(dark, fade, delay);
         setProgressBarDark(dark, fade, delay);
     }
@@ -190,111 +108,6 @@
         }
     }
 
-    private void startIntensityAnimation(ValueAnimator.AnimatorUpdateListener updateListener,
-            boolean dark, long delay, Animator.AnimatorListener listener) {
-        float startIntensity = dark ? 0f : 1f;
-        float endIntensity = dark ? 1f : 0f;
-        ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity);
-        animator.addUpdateListener(updateListener);
-        animator.setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION);
-        animator.setInterpolator(mLinearOutSlowInInterpolator);
-        animator.setStartDelay(delay);
-        if (listener != null) {
-            animator.addListener(listener);
-        }
-        animator.start();
-    }
-
-    private void fadeIconColorFilter(final ImageView target, boolean dark, long delay) {
-        startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                updateIconColorFilter(target, (Float) animation.getAnimatedValue());
-            }
-        }, dark, delay, null /* listener */);
-    }
-
-    private void fadeIconAlpha(final ImageView target, boolean dark, long delay) {
-        startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                float t = (float) animation.getAnimatedValue();
-                target.setImageAlpha((int) (255 * (1f - t) + mIconDarkAlpha * t));
-            }
-        }, dark, delay, null /* listener */);
-    }
-
-    protected void fadeGrayscale(final ImageView target, final boolean dark, long delay) {
-        startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                updateGrayscaleMatrix((float) animation.getAnimatedValue());
-                target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix));
-            }
-        }, dark, delay, new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                if (!dark) {
-                    target.setColorFilter(null);
-                }
-            }
-        });
-    }
-
-    private void updateIconColorFilter(ImageView target, boolean dark) {
-        updateIconColorFilter(target, dark ? 1f : 0f);
-    }
-
-    private void updateIconColorFilter(ImageView target, float intensity) {
-        int color = interpolateColor(mColor, mIconDarkColor, intensity);
-        mIconColorFilter.setColor(color);
-        Drawable iconDrawable = target.getDrawable();
-
-        // Also, the notification might have been modified during the animation, so background
-        // might be null here.
-        if (iconDrawable != null) {
-            iconDrawable.mutate().setColorFilter(mIconColorFilter);
-        }
-    }
-
-    private void updateIconAlpha(ImageView target, boolean dark) {
-        target.setImageAlpha(dark ? mIconDarkAlpha : 255);
-    }
-
-    protected void updateGrayscale(ImageView target, boolean dark) {
-        if (dark) {
-            updateGrayscaleMatrix(1f);
-            target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix));
-        } else {
-            target.setColorFilter(null);
-        }
-    }
-
-    @Override
-    public void setSubTextVisible(boolean visible) {
-        if (mSubText == null) {
-            return;
-        }
-        boolean subTextAvailable = !TextUtils.isEmpty(mSubText.getText());
-        if (visible && subTextAvailable) {
-            mSubText.setVisibility(View.VISIBLE);
-            mSubTextDivider.setVisibility(View.VISIBLE);
-        } else {
-            mSubText.setVisibility(View.GONE);
-            mSubTextDivider.setVisibility(View.GONE);
-        }
-    }
-
-    @Override
-    public void updateExpandability(boolean expandable, View.OnClickListener onClickListener) {
-        mExpandButton.setVisibility(expandable ? View.VISIBLE : View.GONE);
-        mNotificationHeader.setOnClickListener(expandable ? onClickListener : null);
-    }
-
-    private void updateGrayscaleMatrix(float intensity) {
-        mGrayscaleColorMatrix.setSaturation(1 - intensity);
-    }
-
     private static int interpolateColor(int source, int target, float t) {
         int aSource = Color.alpha(source);
         int rSource = Color.red(source);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewWrapper.java
index e83ecb7..61499de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewWrapper.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar;
 
 import android.content.Context;
+import android.view.NotificationHeaderView;
 import android.view.View;
 
 /**
@@ -25,16 +26,13 @@
  */
 public abstract class NotificationViewWrapper {
 
-    private static final String TAG_BIG_MEDIA_NARROW = "bigMediaNarrow";
-    private static final String TAG_MEDIA = "media";
-    private static final String TAG_BIG_PICTURE = "bigPicture";
-
     protected final View mView;
-    private boolean mSubTextVisible = true;
 
     public static NotificationViewWrapper wrap(Context ctx, View v) {
         if (v.getId() == com.android.internal.R.id.status_bar_latest_event_content) {
             return new NotificationTemplateViewWrapper(ctx, v);
+        } else if (v instanceof NotificationHeaderView) {
+            return new NotificationHeaderViewWrapper(ctx, v);
         } else {
             return new NotificationCustomViewWrapper(v);
         }
@@ -56,9 +54,7 @@
     /**
      * Notifies this wrapper that the content of the view might have changed.
      */
-    public void notifyContentUpdated() {
-        setSubTextVisible(mSubTextVisible);
-    }
+    public void notifyContentUpdated() {};
 
     /**
      * @return true if this template might need to be clipped with a round rect to make it look
@@ -69,18 +65,17 @@
     }
 
     /**
-     * Change the subTextVisibility
-     * @param visible Should the subtext be visible
-     */
-    public void setSubTextVisible(boolean visible) {
-        mSubTextVisible = visible;
-    }
-
-    /**
      * Update the appearance of the expand button.
      *
      * @param expandable should this view be expandable
      * @param onClickListener the listener to invoke when the expand affordance is clicked on
      */
     public void updateExpandability(boolean expandable, View.OnClickListener onClickListener) {}
+
+    /**
+     * @return the notification header if it exists
+     */
+    public NotificationHeaderView getNotificationHeader() {
+        return null;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationView.java
index 8f46e89..5fb6fec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationView.java
@@ -18,23 +18,22 @@
 
 import android.annotation.Nullable;
 import android.content.Context;
-import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.widget.TextView;
 
+import com.android.keyguard.AlphaOptimizedLinearLayout;
 import com.android.systemui.R;
-import com.android.systemui.statusbar.AlphaOptimizedFrameLayout;
+import com.android.systemui.ViewInvertHelper;
+import com.android.systemui.statusbar.phone.NotificationPanelView;
 
 /**
  * A hybrid view which may contain information about one ore more notifications.
  */
-public class HybridNotificationView extends AlphaOptimizedFrameLayout {
+public class HybridNotificationView extends AlphaOptimizedLinearLayout {
 
-    protected final int mSingleLineHeight;
-    protected final int mStartMargin;
-    protected final int mEndMargin;
     protected TextView mTitleView;
     protected TextView mTextView;
+    private ViewInvertHelper mInvertHelper;
 
     public HybridNotificationView(Context context) {
         this(context, null);
@@ -51,62 +50,6 @@
     public HybridNotificationView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-        mSingleLineHeight = context.getResources().getDimensionPixelSize(
-                R.dimen.notification_single_line_height);
-        mStartMargin = context.getResources().getDimensionPixelSize(
-                R.dimen.notification_content_margin_start);
-        mEndMargin = context.getResources().getDimensionPixelSize(
-                R.dimen.notification_content_margin_end);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        int totalWidth = MeasureSpec.getSize(widthMeasureSpec);
-        int remainingWidth = totalWidth - mStartMargin - mEndMargin;
-        int newHeightSpec = MeasureSpec.makeMeasureSpec(
-                MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.AT_MOST);
-        int newWidthSpec = MeasureSpec.makeMeasureSpec(remainingWidth, MeasureSpec.AT_MOST);
-        mTitleView.measure(newWidthSpec, newHeightSpec);
-        int maxTitleLength = getResources().getDimensionPixelSize(
-                R.dimen.notification_maximum_title_length);
-        int titleWidth = mTitleView.getMeasuredWidth();
-        int heightSpec = MeasureSpec.makeMeasureSpec(mSingleLineHeight, MeasureSpec.AT_MOST);
-        boolean hasText = !TextUtils.isEmpty(mTextView.getText());
-        if (titleWidth > maxTitleLength && hasText) {
-            titleWidth = maxTitleLength;
-            int widthSpec = MeasureSpec.makeMeasureSpec(titleWidth, MeasureSpec.EXACTLY);
-            mTitleView.measure(widthSpec, heightSpec);
-        }
-        if (hasText) {
-            remainingWidth -= titleWidth;
-            int widthSpec = MeasureSpec.makeMeasureSpec(remainingWidth, MeasureSpec.AT_MOST);
-            mTextView.measure(widthSpec, newHeightSpec);
-        }
-        setMeasuredDimension(totalWidth, mSingleLineHeight);
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        int childLeft = mStartMargin;
-        int childRight = childLeft + mTitleView.getMeasuredWidth();
-        int childBottom = (mSingleLineHeight + mTitleView.getMeasuredHeight()) / 2;
-        int childTop = childBottom - mTitleView.getMeasuredHeight();
-        int rtlLeft = transformForRtl(childLeft);
-        int rtlRight = transformForRtl(childRight);
-        mTitleView.layout(Math.min(rtlLeft, rtlRight), childTop, Math.max(rtlLeft, rtlRight),
-                childBottom);
-        childLeft = childRight;
-        childRight = childLeft + mTextView.getMeasuredWidth();
-        childTop = mTitleView.getTop() + mTitleView.getBaseline() - mTextView.getBaseline();
-        childBottom = childTop + mTextView.getMeasuredHeight();
-        rtlLeft = transformForRtl(childLeft);
-        rtlRight = transformForRtl(childRight);
-        mTextView.layout(Math.min(rtlLeft, rtlRight), childTop, Math.max(rtlLeft, rtlRight),
-                childBottom);
-    }
-
-    private int transformForRtl(int left) {
-        return isLayoutRtl() ? getWidth() - left : left;
     }
 
     @Override
@@ -114,6 +57,7 @@
         super.onFinishInflate();
         mTitleView = (TextView) findViewById(R.id.notification_title);
         mTextView = (TextView) findViewById(R.id.notification_text);
+        mInvertHelper = new ViewInvertHelper(this, NotificationPanelView.DOZE_ANIMATION_DURATION);
     }
 
     public void bind(CharSequence title) {
@@ -125,4 +69,8 @@
         mTextView.setText(text);
         requestLayout();
     }
+
+    public void setDark(boolean dark, boolean fade, long delay) {
+        mInvertHelper.setInverted(dark, fade, delay);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationViewManager.java
index 987f7b8..b8adf5b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationViewManager.java
@@ -68,9 +68,9 @@
     }
 
     private CharSequence resolveText(Notification notification) {
-        CharSequence contentText = notification.extras.getCharSequence(Notification.EXTRA_BIG_TEXT);
+        CharSequence contentText = notification.extras.getCharSequence(Notification.EXTRA_TEXT);
         if (contentText == null) {
-            contentText = notification.extras.getCharSequence(Notification.EXTRA_TEXT);
+            contentText = notification.extras.getCharSequence(Notification.EXTRA_BIG_TEXT);
         }
         return contentText;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
index a2616fe..d35e57b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
@@ -270,7 +270,7 @@
     public void onTuningChanged(String key, String newValue) {
         switch (key) {
             case KEY_DOCK_WINDOW_GESTURE:
-                mDockWindowEnabled = (newValue != null) &&
+                mDockWindowEnabled = (newValue == null) ||
                         (Integer.parseInt(newValue) != 0);
                 break;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
index 08da0d3..f6fc259 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -21,6 +21,7 @@
 
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.NotificationData;
+import com.android.systemui.statusbar.StatusBarState;
 
 import java.util.HashMap;
 import java.util.HashSet;
@@ -146,6 +147,20 @@
         return !group.children.isEmpty();
     }
 
+    public void setStatusBarState(int newState) {
+        if (mBarState == newState) {
+            return;
+        }
+        mBarState = newState;
+        if (mBarState == StatusBarState.KEYGUARD) {
+            for (NotificationGroup group : mGroupMap.values()) {
+                if (group.expanded) {
+                    setGroupExpanded(group, false);
+                }
+            }
+        }
+    }
+
     /**
      * @return whether a given notification is a child in a group which has a summary
      */
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 73ee363..6a2b32d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -44,7 +44,6 @@
 import android.view.animation.PathInterpolator;
 import android.widget.FrameLayout;
 import android.widget.TextView;
-
 import com.android.internal.logging.MetricsLogger;
 import com.android.keyguard.KeyguardStatusView;
 import com.android.systemui.DejankUtils;
@@ -65,7 +64,6 @@
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.stack.StackStateAnimator;
-import com.android.systemui.tuner.TunerService;
 
 import java.util.List;
 
@@ -73,7 +71,7 @@
         ExpandableView.OnHeightChangedListener, ObservableScrollView.Listener,
         View.OnClickListener, NotificationStackScrollLayout.OnOverscrollTopChangedListener,
         KeyguardAffordanceHelper.Callback, NotificationStackScrollLayout.OnEmptySpaceClickListener,
-        HeadsUpManager.OnHeadsUpChangedListener, TunerService.Tunable {
+        HeadsUpManager.OnHeadsUpChangedListener {
 
     private static final boolean DEBUG = false;
 
@@ -221,13 +219,10 @@
     private final Interpolator mTouchResponseInterpolator =
             new PathInterpolator(0.3f, 0f, 0.1f, 1f);
 
-    private boolean mNewQs;
-
     public NotificationPanelView(Context context, AttributeSet attrs) {
         super(context, attrs);
         setWillNotDraw(!DEBUG);
         mFalsingManager = FalsingManager.getInstance(context);
-        TunerService.get(context).addTunable(this, QSPanel.QS_THE_NEW_QS);
     }
 
     public void setStatusBar(PhoneStatusBar bar) {
@@ -235,26 +230,10 @@
     }
 
     @Override
-    public void onTuningChanged(String key, String newValue) {
-        if (QSPanel.QS_THE_NEW_QS.equals(key)) {
-            boolean b = newValue != null && Integer.parseInt(newValue) != 0;
-            if (mNewQs != b) {
-                if (mHeader != null) {
-                    // We are too late, no good way to re-initialize yet, just die and come back up.
-                    android.os.Process.killProcess(android.os.Process.myPid());
-                } else {
-                    mNewQs = b;
-                }
-            }
-        }
-    }
-
-    @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
         ViewStub stub = (ViewStub) findViewById(R.id.status_bar_header);
-        stub.setLayoutResource(mNewQs
-                ? R.layout.quick_status_bar_expanded_header : R.layout.status_bar_expanded_header);
+        stub.setLayoutResource(R.layout.quick_status_bar_expanded_header);
         mHeader = (BaseStatusBarHeader) stub.inflate();
         mHeader.setOnClickListener(this);
         mKeyguardStatusBar = (KeyguardStatusBarView) findViewById(R.id.keyguard_header);
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 e9d6bf0..b854c80 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -2233,6 +2233,10 @@
         mHandler.post(mAnimateCollapsePanels);
     }
 
+    public void postAnimateOpenPanels() {
+        mHandler.sendEmptyMessage(MSG_OPEN_SETTINGS_PANEL);
+    }
+
     public void animateCollapsePanels(int flags) {
         animateCollapsePanels(flags, false /* force */, false /* delayed */,
                 1.0f /* speedUpFactor */);
@@ -3132,10 +3136,6 @@
         mNaturalBarHeight = res.getDimensionPixelSize(
                 com.android.internal.R.dimen.status_bar_height);
 
-        mRowMinHeightLegacy =  res.getDimensionPixelSize(R.dimen.notification_min_height_legacy);
-        mRowMinHeight =  res.getDimensionPixelSize(R.dimen.notification_min_height);
-        mRowMaxHeight =  res.getDimensionPixelSize(R.dimen.notification_max_height);
-
         mMaxAllowedKeyguardNotifications = res.getInteger(R.integer.keyguard_max_notification_count);
 
         if (DEBUG) Log.v(TAG, "updateResources");
@@ -3282,6 +3282,16 @@
         return !isDeviceProvisioned() || (mDisabled1 & StatusBarManager.DISABLE_SEARCH) != 0;
     }
 
+    public void postQSRunnableDismissingKeyguard(final Runnable runnable) {
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mLeaveOpenOnKeyguardHide = true;
+                executeRunnableDismissingKeyguard(runnable, null, false, true);
+            }
+        });
+    }
+
     public void postStartActivityDismissingKeyguard(final PendingIntent intent) {
         mHandler.post(new Runnable() {
             @Override
@@ -3862,6 +3872,7 @@
             clearNotificationEffects();
         }
         mState = state;
+        mGroupManager.setStatusBarState(state);
         mFalsingManager.setStatusBarState(state);
         mStatusBarWindowManager.setStatusBarState(state);
         updateDozing();
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 83edc96..b89cd22 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -16,11 +16,12 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.AlarmManager;
 import android.app.AlarmManager.AlarmClockInfo;
-import android.app.IUserSwitchObserver;
 import android.app.StatusBarManager;
+import android.app.SynchronousUserSwitchObserver;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -28,7 +29,6 @@
 import android.content.pm.UserInfo;
 import android.media.AudioManager;
 import android.os.Handler;
-import android.os.IRemoteCallback;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -72,6 +72,7 @@
     private final HotspotController mHotspot;
     private final AlarmManager mAlarmManager;
     private final UserInfoController mUserInfoController;
+    private final UserManager mUserManager;
 
     // Assume it's all good unless we hear otherwise.  We don't always seem
     // to get broadcasts that it *is* there.
@@ -84,7 +85,8 @@
     private int mZen;
 
     private boolean mManagedProfileFocused = false;
-    private boolean mManagedProfileIconVisible = true;
+    private boolean mManagedProfileIconVisible = false;
+    private boolean mManagedProfileInQuietMode = false;
 
     private boolean mKeyguardVisible = true;
     private BluetoothController mBluetooth;
@@ -106,6 +108,10 @@
             else if (action.equals(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED)) {
                 updateTTY(intent);
             }
+            else if (action.equals(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED)) {
+                updateQuietState();
+                updateManagedProfile();
+            }
         }
     };
 
@@ -127,6 +133,7 @@
         mService = (StatusBarManager) context.getSystemService(Context.STATUS_BAR_SERVICE);
         mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
         mUserInfoController = userInfoController;
+        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
 
         // listen for broadcasts
         IntentFilter filter = new IntentFilter();
@@ -135,6 +142,7 @@
         filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
         filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
         filter.addAction(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED);
+        filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED);
         mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
 
         // listen for user / profile change.
@@ -178,7 +186,7 @@
         // managed profile
         mService.setIcon(SLOT_MANAGED_PROFILE, R.drawable.stat_sys_managed_profile_status, 0,
                 mContext.getString(R.string.accessibility_managed_profile));
-        mService.setIconVisibility(SLOT_MANAGED_PROFILE, false);
+        mService.setIconVisibility(SLOT_MANAGED_PROFILE, mManagedProfileIconVisible);
     }
 
     public void setZenMode(int zen) {
@@ -349,8 +357,18 @@
         }
     }
 
+    private void updateQuietState() {
+        mManagedProfileInQuietMode = false;
+        int currentUserId = ActivityManager.getCurrentUser();
+        for (UserInfo ui : mUserManager.getEnabledProfiles(currentUserId)) {
+            if (ui.isManagedProfile() && ui.isQuietModeEnabled()) {
+                mManagedProfileInQuietMode = true;
+                return;
+            }
+        }
+    }
+
     private void profileChanged(int userId) {
-        UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
         UserInfo user = null;
         if (userId == UserHandle.USER_CURRENT) {
             try {
@@ -359,7 +377,7 @@
                 // Ignore
             }
         } else {
-            user = userManager.getUserInfo(userId);
+            user = mUserManager.getUserInfo(userId);
         }
 
         mManagedProfileFocused = user != null && user.isManagedProfile();
@@ -371,30 +389,37 @@
         if (DEBUG) Log.v(TAG, "updateManagedProfile: mManagedProfileFocused: "
                 + mManagedProfileFocused
                 + " mKeyguardVisible: " + mKeyguardVisible);
-        boolean showIcon = mManagedProfileFocused && !mKeyguardVisible;
+        final boolean showIcon;
+        if (mManagedProfileFocused && !mKeyguardVisible) {
+            showIcon = true;
+            mService.setIcon(SLOT_MANAGED_PROFILE, R.drawable.stat_sys_managed_profile_status, 0,
+                    mContext.getString(R.string.accessibility_managed_profile));
+        } else if (mManagedProfileInQuietMode) {
+            showIcon = true;
+            mService.setIcon(SLOT_MANAGED_PROFILE, R.drawable.stat_sys_managed_profile_status_off, 0,
+                    mContext.getString(R.string.accessibility_managed_profile));
+        } else {
+            showIcon = false;
+        }
         if (mManagedProfileIconVisible != showIcon) {
             mService.setIconVisibility(SLOT_MANAGED_PROFILE, showIcon);
             mManagedProfileIconVisible = showIcon;
         }
     }
 
-    private final IUserSwitchObserver.Stub mUserSwitchListener =
-            new IUserSwitchObserver.Stub() {
+    private final SynchronousUserSwitchObserver mUserSwitchListener =
+            new SynchronousUserSwitchObserver() {
                 @Override
-                public void onUserSwitching(int newUserId, IRemoteCallback reply) {
+                public void onUserSwitching(int newUserId) throws RemoteException {
                     mUserInfoController.reloadUserInfo();
-                    if (reply != null) {
-                        try {
-                            reply.sendResult(null);
-                        } catch (RemoteException e) {
-                        }
-                    }
                 }
 
                 @Override
                 public void onUserSwitchComplete(int newUserId) throws RemoteException {
                     updateAlarm();
                     profileChanged(newUserId);
+                    updateQuietState();
+                    updateManagedProfile();
                 }
 
                 @Override
@@ -430,5 +455,6 @@
         if (mCurrentUserSetup == userSetup) return;
         mCurrentUserSetup = userSetup;
         updateAlarm();
+        updateQuietState();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index f7ff8aa..7f27ba7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.app.ActivityManager;
 import android.app.PendingIntent;
 import android.content.ComponentName;
 import android.content.Context;
@@ -27,10 +28,11 @@
 import android.os.Looper;
 import android.os.Process;
 import android.os.RemoteException;
+import android.provider.Settings;
 import android.service.quicksettings.IQSService;
 import android.service.quicksettings.Tile;
+import android.text.TextUtils;
 import android.util.Log;
-
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.qs.tiles.AirplaneModeTile;
@@ -45,15 +47,10 @@
 import com.android.systemui.qs.tiles.HotspotTile;
 import com.android.systemui.qs.tiles.IntentTile;
 import com.android.systemui.qs.tiles.LocationTile;
-import com.android.systemui.qs.tiles.QAirplaneTile;
-import com.android.systemui.qs.tiles.QBluetoothTile;
-import com.android.systemui.qs.tiles.QFlashlightTile;
-import com.android.systemui.qs.tiles.QLockTile;
-import com.android.systemui.qs.tiles.QRotationLockTile;
-import com.android.systemui.qs.tiles.QWifiTile;
 import com.android.systemui.qs.tiles.RotationLockTile;
 import com.android.systemui.qs.tiles.UserTile;
 import com.android.systemui.qs.tiles.WifiTile;
+import com.android.systemui.qs.tiles.WorkModeTile;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.BluetoothController;
 import com.android.systemui.statusbar.policy.CastController;
@@ -136,7 +133,7 @@
         TunerService.get(mContext).addTunable(this, TILES_SETTING);
     }
 
-    PhoneStatusBar getPhoneStatusBar() {
+    public PhoneStatusBar getPhoneStatusBar() {
         return mStatusBar;
     }
 
@@ -165,6 +162,11 @@
     }
 
     @Override
+    public void startRunnableDismissingKeyguard(Runnable runnable) {
+        mStatusBar.postQSRunnableDismissingKeyguard(runnable);
+    }
+
+    @Override
     public void warn(String message, Throwable t) {
         // already logged
     }
@@ -175,6 +177,11 @@
     }
 
     @Override
+    public void openPanels() {
+        mStatusBar.postAnimateOpenPanels();
+    }
+
+    @Override
     public Looper getLooper() {
         return mLooper;
     }
@@ -272,8 +279,10 @@
                 if (DEBUG) Log.d(TAG, "Creating tile: " + tileSpec);
                 try {
                     QSTile<?> tile = createTile(tileSpec);
-                    tile.setTileSpec(tileSpec);
-                    newTiles.put(tileSpec, tile);
+                    if (tile != null) {
+                        tile.setTileSpec(tileSpec);
+                        newTiles.put(tileSpec, tile);
+                    }
                 } catch (Throwable t) {
                     Log.w(TAG, "Error creating tile for spec: " + tileSpec, t);
                 }
@@ -289,6 +298,14 @@
     }
 
     @Override
+    public void removeTile(String tileSpec) {
+        ArrayList<String> specs = new ArrayList<>(mTileSpecs);
+        specs.remove(tileSpec);
+        Settings.Secure.putStringForUser(mContext.getContentResolver(), TILES_SETTING,
+                TextUtils.join(",", specs), ActivityManager.getCurrentUser());
+    }
+
+    @Override
     public void updateQsTile(Tile tile) throws RemoteException {
         verifyCaller(tile.getComponentName().getPackageName());
         CustomTile customTile = getTileForComponent(tile.getComponentName());
@@ -333,12 +350,17 @@
     }
 
     public QSTile<?> createTile(String tileSpec) {
-        if (tileSpec.equals("wifi")) return new WifiTile(this, false);
-        else if (tileSpec.equals("bt")) return new BluetoothTile(this, false);
+        if (tileSpec.equals("wifi")) return WifiTile.isSupported(this)
+                ? new WifiTile(this) : null;
+        else if (tileSpec.equals("bt")) return BluetoothTile.isSupported(this)
+                ? new BluetoothTile(this) : null;
+        else if (tileSpec.equals("cell")) return CellularTile.isSupported(this)
+                ? new CellularTile(this) : null;
+        else if (tileSpec.equals("dnd")) return DndTile.isSupported(this)
+                ? new DndTile(this) : null;
         else if (tileSpec.equals("inversion")) return new ColorInversionTile(this);
-        else if (tileSpec.equals("cell")) return new CellularTile(this);
         else if (tileSpec.equals("airplane")) return new AirplaneModeTile(this);
-        else if (tileSpec.equals("dnd")) return new DndTile(this);
+        else if (tileSpec.equals("work")) return new WorkModeTile(this);
         else if (tileSpec.equals("rotation")) return new RotationLockTile(this);
         else if (tileSpec.equals("flashlight")) return new FlashlightTile(this);
         else if (tileSpec.equals("location")) return new LocationTile(this);
@@ -346,16 +368,6 @@
         else if (tileSpec.equals("hotspot")) return new HotspotTile(this);
         else if (tileSpec.equals("user")) return new UserTile(this);
         else if (tileSpec.equals("battery")) return new BatteryTile(this);
-        // Detail only versions of wifi and bluetooth.
-        else if (tileSpec.equals("dwifi")) return new WifiTile(this, true);
-        else if (tileSpec.equals("dbt")) return new BluetoothTile(this, true);
-        // Quick tiles, no text.
-        else if (tileSpec.equals("qwifi")) return new QWifiTile(this);
-        else if (tileSpec.equals("qbt")) return new QBluetoothTile(this);
-        else if (tileSpec.equals("qairplane")) return new QAirplaneTile(this);
-        else if (tileSpec.equals("qrotation")) return new QRotationLockTile(this);
-        else if (tileSpec.equals("qflashlight")) return new QFlashlightTile(this);
-        else if (tileSpec.equals("qlock")) return new QLockTile(this);
         // Intent tiles.
         else if (tileSpec.startsWith(IntentTile.PREFIX)) return IntentTile.create(this,tileSpec);
         else if (tileSpec.startsWith(CustomTile.PREFIX)) return CustomTile.create(this,tileSpec);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
index cc9f5c7..1372cca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
@@ -24,16 +24,18 @@
 import android.graphics.drawable.Animatable;
 import android.graphics.drawable.RippleDrawable;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.Switch;
 import android.widget.TextView;
 import android.widget.Toast;
-
+import com.android.keyguard.KeyguardStatusView;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.qs.QSTile;
+import com.android.systemui.qs.QuickQSPanel;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.NextAlarmController;
 import com.android.systemui.statusbar.policy.UserInfoController;
@@ -42,6 +44,7 @@
 public class QuickStatusBarHeader extends BaseStatusBarHeader implements
         NextAlarmController.NextAlarmChangeCallback, View.OnClickListener {
 
+    private static final String TAG = "QuickStatusBarHeader";
     private ActivityStarter mActivityStarter;
     private NextAlarmController mNextAlarmController;
     private SettingsButton mSettingsButton;
@@ -59,11 +62,15 @@
 
     private boolean mDetailTransitioning;
     private ViewGroup mExpandedGroup;
+    private ViewGroup mDateTimeGroup;
+    private View mEmergencyOnly;
     private TextView mQsDetailHeaderTitle;
     private boolean mListening;
     private AlarmManager.AlarmClockInfo mNextAlarm;
 
-    private QSPanel mHeaderQsPanel;
+    private QuickQSPanel mHeaderQsPanel;
+    private boolean mShowEmergencyCallsOnly;
+    private float mDateTimeTranslation;
 
     public QuickStatusBarHeader(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -73,9 +80,13 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
 
+        mEmergencyOnly = findViewById(R.id.header_emergency_calls_only);
+        mDateTimeTranslation = mContext.getResources().getDimension(
+                R.dimen.qs_date_anim_translation);
+        mDateTimeGroup = (ViewGroup) findViewById(R.id.date_time_group);
         mExpandedGroup = (ViewGroup) findViewById(R.id.expanded_group);
 
-        mHeaderQsPanel = (QSPanel) findViewById(R.id.quick_qs_panel);
+        mHeaderQsPanel = (QuickQSPanel) findViewById(R.id.quick_qs_panel);
 
         mSettingsButton = (SettingsButton) findViewById(R.id.settings_button);
         mSettingsContainer = findViewById(R.id.settings_button_container);
@@ -118,14 +129,15 @@
     @Override
     public void setExpanded(boolean expanded) {
         mExpanded = expanded;
+        updateEverything();
     }
 
     @Override
     public void onNextAlarmChanged(AlarmManager.AlarmClockInfo nextAlarm) {
         mNextAlarm = nextAlarm;
+        Log.d(TAG, "Got alarm update " + (nextAlarm != null));
         if (nextAlarm != null) {
-            // TODO:...
-//            mAlarmStatus.setText(KeyguardStatusView.formatNextAlarm(getContext(), nextAlarm));
+            mAlarmStatus.setText(KeyguardStatusView.formatNextAlarm(getContext(), nextAlarm));
         }
         mAlarmShowing = nextAlarm != null;
         updateEverything();
@@ -133,9 +145,13 @@
 
     @Override
     public void setExpansion(float headerExpansionFraction) {
-        float offset = getHeight() * headerExpansionFraction;
-        mExpandedGroup.setTranslationY(offset - getHeight());
-        mHeaderQsPanel.setTranslationY(offset);
+        mExpandedGroup.setAlpha(headerExpansionFraction);
+        mExpandedGroup.setVisibility(headerExpansionFraction > 0 ? View.VISIBLE : View.INVISIBLE);
+        mHeaderQsPanel.setAlpha(1 - headerExpansionFraction);
+        mHeaderQsPanel.setVisibility(headerExpansionFraction < 1 ? View.VISIBLE : View.INVISIBLE);
+
+        mDateTimeGroup.setTranslationY(headerExpansionFraction * mDateTimeTranslation);
+        mEmergencyOnly.setAlpha(headerExpansionFraction);
     }
 
     public void setListening(boolean listening) {
@@ -153,16 +169,20 @@
     }
 
     private void updateVisibilities() {
-        mAlarmStatus.setVisibility(mExpanded && mAlarmShowing ? View.VISIBLE : View.GONE);
+        mAlarmStatus.setVisibility(mAlarmShowing ? View.VISIBLE : View.GONE);
         mQsDetailHeader.setVisibility(mExpanded && mShowingDetail ? View.VISIBLE : View.INVISIBLE);
+        mEmergencyOnly.setVisibility(mExpanded && mShowEmergencyCallsOnly
+                ? View.VISIBLE : View.INVISIBLE);
         mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility(
                 TunerService.isTunerEnabled(mContext) ? View.VISIBLE : View.INVISIBLE);
     }
 
     private void updateListeners() {
         if (mListening) {
+            Log.d(TAG, "Listening for Alarms");
             mNextAlarmController.addStateChangedCallback(this);
         } else {
+            Log.d(TAG, "Not listening for Alarms");
             mNextAlarmController.removeStateChangedCallback(this);
         }
     }
@@ -190,7 +210,9 @@
                 host.getUserSwitcherController(), host.getUserInfoController(),
                 host.getKeyguardMonitor(), host.getSecurityController(),
                 host.getBatteryController());
+        mHeaderQsPanel.setQSPanelAndHeader(mQsPanel, this);
         mHeaderQsPanel.setHost(myHost);
+        mHeaderQsPanel.setMaxTiles(5);
         mHeaderQsPanel.setTiles(myHost.getTiles());
         myHost.addCallback(new QSTile.Host.Callback() {
             @Override
@@ -247,8 +269,14 @@
     }
 
     @Override
-    public void setEmergencyCallsOnly(boolean emergencyOnly) {
-        // Don't care.
+    public void setEmergencyCallsOnly(boolean show) {
+        boolean changed = show != mShowEmergencyCallsOnly;
+        if (changed) {
+            mShowEmergencyCallsOnly = show;
+            if (mExpanded) {
+                updateEverything();
+            }
+        }
     }
 
     private final QSPanel.Callback mQsPanelCallback = new QSPanel.Callback() {
@@ -305,6 +333,7 @@
 
         private void handleShowingDetail(final QSTile.DetailAdapter detail) {
             final boolean showingDetail = detail != null;
+            transition(mDateTimeGroup, !showingDetail);
             transition(mExpandedGroup, !showingDetail);
             if (mAlarmShowing) {
                 transition(mAlarmStatus, !showingDetail);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index 6cda561..3d21f44 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -59,7 +59,7 @@
  */
 public class StatusBarHeaderView extends BaseStatusBarHeader implements View.OnClickListener,
         BatteryController.BatteryStateChangeCallback, NextAlarmController.NextAlarmChangeCallback,
-        EmergencyListener, TunerService.Tunable {
+        EmergencyListener {
 
     private boolean mExpanded;
     private boolean mListening;
@@ -234,28 +234,6 @@
         updateClockCollapsedMargin();
     }
 
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        TunerService.get(mContext).addTunable(this, QSPanel.QS_THE_NEW_QS);
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        TunerService.get(mContext).removeTunable(this);
-    }
-
-    @Override
-    public void onTuningChanged(String key, String newValue) {
-        if (QSPanel.QS_THE_NEW_QS.equals(key)) {
-            mAllowExpand = newValue == null || Integer.parseInt(newValue) == 0;
-            if (!mAllowExpand) {
-                setExpanded(false);
-            }
-        }
-    }
-
     private void updateClockCollapsedMargin() {
         Resources res = getResources();
         int padding = res.getDimensionPixelSize(R.dimen.clock_collapsed_bottom_margin);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 22c0cb9..65053f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -28,6 +28,8 @@
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.KeyEvent;
@@ -49,7 +51,7 @@
 /**
  * Host for the remote input.
  */
-public class RemoteInputView extends LinearLayout implements View.OnClickListener {
+public class RemoteInputView extends LinearLayout implements View.OnClickListener, TextWatcher {
 
     private static final String TAG = "RemoteInput";
 
@@ -101,6 +103,7 @@
             }
         });
         mEditText.setOnClickListener(this);
+        mEditText.addTextChangedListener(this);
         mEditText.setInnerFocusable(false);
         mEditText.mDefocusListener = this;
     }
@@ -115,6 +118,8 @@
         mEditText.setEnabled(false);
         mSendButton.setVisibility(INVISIBLE);
         mProgressBar.setVisibility(VISIBLE);
+        mController.removeRemoteInput(mEntry);
+        mEditText.mShowImeOnInputConnection = false;
 
         try {
             mPendingIntent.send(mContext, 0, fillInIntent);
@@ -175,6 +180,40 @@
         mEditText.setText(mEntry.remoteInputText);
         mEditText.setSelection(mEditText.getText().length());
         mEditText.requestFocus();
+        updateSendButton();
+    }
+
+    public void onNotificationUpdate() {
+        boolean sending = mProgressBar.getVisibility() == VISIBLE;
+
+        if (sending) {
+            // Update came in after we sent the reply, time to reset.
+            reset();
+        }
+    }
+
+    private void reset() {
+        mEditText.getText().clear();
+        mEditText.setEnabled(true);
+        mSendButton.setVisibility(VISIBLE);
+        mProgressBar.setVisibility(INVISIBLE);
+        updateSendButton();
+        onDefocus();
+    }
+
+    private void updateSendButton() {
+        mSendButton.setEnabled(mEditText.getText().length() != 0);
+    }
+
+    @Override
+    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+    @Override
+    public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+    @Override
+    public void afterTextChanged(Editable s) {
+        updateSendButton();
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
index 77a9871..2b71ce9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
@@ -23,9 +23,11 @@
 import android.view.ViewGroup;
 
 import com.android.systemui.R;
+import com.android.systemui.ViewInvertHelper;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.HybridNotificationView;
 import com.android.systemui.statusbar.notification.HybridNotificationViewManager;
+import com.android.systemui.statusbar.phone.NotificationPanelView;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -46,9 +48,10 @@
     private final List<ExpandableNotificationRow> mChildren = new ArrayList<>();
     private final int mNotificationHeaderHeight;
     private final int mNotificationAppearDistance;
-    private final float mHeaderTopPaddingSubstraction;
+    private final int mNotificatonTopPadding;
     private final HybridNotificationViewManager mHybridViewManager;
     private final float mCollapsedBottompadding;
+    private ViewInvertHelper mOverflowInvertHelper;
     private boolean mChildrenExpanded;
     private ExpandableNotificationRow mNotificationParent;
     private HybridNotificationView mGroupOverflowContainer;
@@ -78,28 +81,23 @@
         mNotificationAppearDistance = getResources().getDimensionPixelSize(
                 R.dimen.notification_appear_distance);
         mNotificationHeaderHeight = getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.notification_header_height);
-        mHeaderTopPaddingSubstraction = 2 * getResources().getDisplayMetrics().density;
-        mCollapsedBottompadding = 10 * getResources().getDisplayMetrics().density;
+                com.android.internal.R.dimen.notification_content_margin_top);
+        mNotificatonTopPadding = getResources().getDimensionPixelSize(
+                R.dimen.notification_children_container_top_padding);
+        mCollapsedBottompadding = 11.5f * getResources().getDisplayMetrics().density;
         mHybridViewManager = new HybridNotificationViewManager(getContext(), this);
     }
 
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         int childCount = mChildren.size();
-        boolean firstChild = true;
         for (int i = 0; i < childCount; i++) {
             View child = mChildren.get(i);
-            boolean viewGone = child.getVisibility() == View.GONE;
-            if (viewGone) {
+            if (child.getVisibility() == View.GONE) {
                 continue;
             }
             child.layout(0, 0, getWidth(), child.getMeasuredHeight());
-            if (!firstChild) {
-                mDividers.get(i - 1).layout(0, 0, getWidth(), mDividerHeight);
-            } else {
-                firstChild = false;
-            }
+            mDividers.get(i).layout(0, 0, getWidth(), mDividerHeight);
         }
         if (mGroupOverflowContainer != null) {
             mGroupOverflowContainer.layout(0, 0, getWidth(),
@@ -119,21 +117,17 @@
         }
         int newHeightSpec = MeasureSpec.makeMeasureSpec(ownMaxHeight, MeasureSpec.AT_MOST);
         int dividerHeightSpec = MeasureSpec.makeMeasureSpec(mDividerHeight, MeasureSpec.EXACTLY);
-        int height = mNotificationHeaderHeight;
+        int height = mNotificationHeaderHeight + mNotificatonTopPadding;
         int childCount = mChildren.size();
-        boolean firstChild = true;
         for (int i = 0; i < childCount; i++) {
             View child = mChildren.get(i);
             child.measure(widthMeasureSpec, newHeightSpec);
             height += child.getMeasuredHeight();
-            if (!firstChild) {
-                // layout the divider
-                View divider = mDividers.get(i - 1);
-                divider.measure(widthMeasureSpec, dividerHeightSpec);
-                height += mChildPadding;
-            } else {
-                firstChild = false;
-            }
+
+            // layout the divider
+            View divider = mDividers.get(i);
+            divider.measure(widthMeasureSpec, dividerHeightSpec);
+            height += mDividerHeight;
         }
         int width = MeasureSpec.getSize(widthMeasureSpec);
         if (mGroupOverflowContainer != null) {
@@ -152,11 +146,11 @@
         int newIndex = childIndex < 0 ? mChildren.size() : childIndex;
         mChildren.add(newIndex, row);
         addView(row);
-        if (mChildren.size() != 1) {
-            View divider = inflateDivider();
-            addView(divider);
-            mDividers.add(Math.max(newIndex - 1, 0), divider);
-        }
+
+        View divider = inflateDivider();
+        addView(divider);
+        mDividers.add(newIndex, divider);
+
         updateGroupOverflow();
     }
 
@@ -164,10 +158,10 @@
         int childIndex = mChildren.indexOf(row);
         mChildren.remove(row);
         removeView(row);
-        if (!mDividers.isEmpty()) {
-            View divider = mDividers.remove(Math.max(childIndex - 1, 0));
-            removeView(divider);
-        }
+
+        View divider = mDividers.remove(childIndex);
+        removeView(divider);
+
         row.setSystemChildExpanded(false);
         updateGroupOverflow();
     }
@@ -181,12 +175,17 @@
         if (hasOverflow) {
             mGroupOverflowContainer = mHybridViewManager.bindFromNotificationGroup(
                     mGroupOverflowContainer, mChildren, lastVisibleIndex + 1);
+            if (mOverflowInvertHelper == null) {
+                mOverflowInvertHelper= new ViewInvertHelper(mGroupOverflowContainer,
+                        NotificationPanelView.DOZE_ANIMATION_DURATION);
+            }
             if (mGroupOverFlowState == null) {
                 mGroupOverFlowState = new ViewState();
             }
         } else if (mGroupOverflowContainer != null) {
             removeView(mGroupOverflowContainer);
             mGroupOverflowContainer = null;
+            mOverflowInvertHelper = null;
             mGroupOverFlowState = null;
         }
     }
@@ -246,7 +245,10 @@
      *         in @param maxAllowedVisibleChildren
      */
     private int getIntrinsicHeight(float maxAllowedVisibleChildren) {
-        int intrinsicHeight = mNotificationHeaderHeight;;
+        int intrinsicHeight = mNotificationHeaderHeight;
+        if (mChildrenExpanded) {
+            intrinsicHeight += mNotificatonTopPadding;
+        }
         int visibleChildren = 0;
         int childCount = mChildren.size();
         for (int i = 0; i < childCount; i++) {
@@ -254,14 +256,15 @@
                 break;
             }
             ExpandableNotificationRow child = mChildren.get(i);
-            if (i == 0 && child.hasSameBgColor(mNotificationParent)) {
-                intrinsicHeight -= mHeaderTopPaddingSubstraction;
-            }
             intrinsicHeight += child.getIntrinsicHeight();
             visibleChildren++;
         }
         if (visibleChildren > 0) {
-            intrinsicHeight += (visibleChildren - 1) * mDividerHeight;
+            if (mChildrenExpanded) {
+                intrinsicHeight += visibleChildren * mDividerHeight;
+            } else {
+                intrinsicHeight += (visibleChildren - 1) * mChildPadding;
+            }
         }
         if (!mChildrenExpanded) {
             intrinsicHeight += mCollapsedBottompadding;
@@ -288,12 +291,9 @@
         for (int i = 0; i < childCount; i++) {
             ExpandableNotificationRow child = mChildren.get(i);
             if (!firstChild) {
-                // There's a divider
-                yPosition += mChildPadding;
+                yPosition += mChildrenExpanded ? mDividerHeight : mChildPadding;
             } else {
-                if (child.hasSameBgColor(mNotificationParent)) {
-                    yPosition -= mHeaderTopPaddingSubstraction;
-                }
+                yPosition += mChildrenExpanded ? mNotificatonTopPadding + mDividerHeight : 0;
                 firstChild = false;
             }
             StackViewState childState = resultState.getViewStateForView(child);
@@ -332,7 +332,7 @@
         if (!likeCollapsed && (mChildrenExpanded || mNotificationParent.isUserLocked())) {
             return NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED;
         }
-        if (mNotificationParent.isExpanded()) {
+        if (mNotificationParent.isExpanded() || mNotificationParent.isHeadsUp()) {
             return NUMBER_OF_CHILDREN_WHEN_SYSTEM_EXPANDED;
         }
         return NUMBER_OF_CHILDREN_WHEN_COLLAPSED;
@@ -340,23 +340,18 @@
 
     public void applyState(StackScrollState state) {
         int childCount = mChildren.size();
-        boolean firstChild = true;
         ViewState tmpState = new ViewState();
         for (int i = 0; i < childCount; i++) {
             ExpandableNotificationRow child = mChildren.get(i);
             StackViewState viewState = state.getViewStateForView(child);
-            if (!firstChild) {
-                // layout the divider
-                View divider = mDividers.get(i - 1);
-                tmpState.initFrom(divider);
-                tmpState.yTranslation = (int) (viewState.yTranslation
-                        - (mChildPadding + mDividerHeight) / 2.0f);
-                tmpState.alpha = mChildrenExpanded && viewState.alpha != 0 ? 0.5f : 0;
-                state.applyViewState(divider, tmpState);
-            } else {
-                firstChild = false;
-            }
             state.applyState(child, viewState);
+
+            // layout the divider
+            View divider = mDividers.get(i);
+            tmpState.initFrom(divider);
+            tmpState.yTranslation = viewState.yTranslation - mDividerHeight;
+            tmpState.alpha = mChildrenExpanded && viewState.alpha != 0 ? 0.5f : 0;
+            state.applyViewState(divider, tmpState);
         }
         if (mGroupOverflowContainer != null) {
             state.applyViewState(mGroupOverflowContainer, mGroupOverFlowState);
@@ -375,61 +370,57 @@
             return;
         }
         int childCount = mChildren.size();
-        boolean firstChild = true;
         StackViewState sourceState = new StackViewState();
         ViewState dividerState = new ViewState();
         for (int i = 0; i < childCount; i++) {
             ExpandableNotificationRow child = mChildren.get(i);
             StackViewState viewState = state.getViewStateForView(child);
-            if (!firstChild) {
-                // layout the divider
-                View divider = mDividers.get(i - 1);
-                dividerState.initFrom(divider);
-                dividerState.yTranslation = viewState.yTranslation
-                        - (mChildPadding + mDividerHeight) / 2.0f + mNotificationAppearDistance;
-                dividerState.alpha = 0;
-                state.applyViewState(divider, dividerState);
-            } else {
-                firstChild = false;
-            }
             sourceState.copyFrom(viewState);
             sourceState.alpha = 0;
             sourceState.yTranslation += mNotificationAppearDistance;
             state.applyState(child, sourceState);
+
+            // layout the divider
+            View divider = mDividers.get(i);
+            dividerState.initFrom(divider);
+            dividerState.yTranslation = viewState.yTranslation - mDividerHeight
+                    + mNotificationAppearDistance;
+            dividerState.alpha = 0;
+            state.applyViewState(divider, dividerState);
+
         }
     }
 
     public void startAnimationToState(StackScrollState state, StackStateAnimator stateAnimator,
             boolean withDelays, long baseDelay, long duration) {
         int childCount = mChildren.size();
-        boolean firstChild = true;
         ViewState tmpState = new ViewState();
-        int notGoneIndex = 0;
-        for (int i = 0; i < childCount; i++) {
+        int delayIndex = 0;
+        int maxAllowChildCount = getMaxAllowedVisibleChildren(true /* likeCollapsed */);
+        for (int i = childCount - 1; i >= 0; i--) {
             ExpandableNotificationRow child = mChildren.get(i);
             StackViewState viewState = state.getViewStateForView(child);
             int difference = Math.min(StackStateAnimator.DELAY_EFFECT_MAX_INDEX_DIFFERENCE_CHILDREN,
-                    notGoneIndex + 1);
+                    delayIndex);
             long delay = withDelays
                     ? difference * StackStateAnimator.ANIMATION_DELAY_PER_ELEMENT_EXPAND_CHILDREN
                     : 0;
-            delay += baseDelay;
-            if (!firstChild) {
-                // layout the divider
-                View divider = mDividers.get(i - 1);
-                tmpState.initFrom(divider);
-                tmpState.yTranslation = viewState.yTranslation
-                        - (mChildPadding + mDividerHeight) / 2.0f;
-                tmpState.alpha = mChildrenExpanded && viewState.alpha != 0 ? 0.5f : 0;;
-                stateAnimator.startViewAnimations(divider, tmpState, delay, duration);
-            } else {
-                firstChild = false;
-            }
+            delay = (long) (delay * (mChildrenExpanded ? 1.0f : 0.5f) + baseDelay);
             stateAnimator.startStackAnimations(child, viewState, state, -1, delay);
-            notGoneIndex++;
+
+            // layout the divider
+            View divider = mDividers.get(i);
+            tmpState.initFrom(divider);
+            tmpState.yTranslation = viewState.yTranslation - mDividerHeight;
+            tmpState.alpha = mChildrenExpanded && viewState.alpha != 0 ? 0.5f : 0;
+            stateAnimator.startViewAnimations(divider, tmpState, delay, duration);
+            if (i < maxAllowChildCount) {
+                delayIndex++;
+            }
         }
         if (mGroupOverflowContainer != null) {
-            stateAnimator.startViewAnimations(mGroupOverflowContainer, mGroupOverFlowState, -1, 0);
+            stateAnimator.startViewAnimations(mGroupOverflowContainer, mGroupOverFlowState,
+                    baseDelay, duration);
         }
     }
 
@@ -463,4 +454,10 @@
     public int getMinHeight() {
         return getIntrinsicHeight(getMaxAllowedVisibleChildren(true /* forceCollapsed */));
     }
+
+    public void setDark(boolean dark, boolean fade, long delay) {
+        if (mGroupOverflowContainer != null) {
+            mOverflowInvertHelper.setInverted(dark, fade, delay);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/QSPagingSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/QSPagingSwitch.java
index 04a51f0..d19a825 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/QSPagingSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/QSPagingSwitch.java
@@ -9,8 +9,8 @@
 public class QSPagingSwitch extends TunerSwitch {
 
     public static final String QS_PAGE_TILES =
-            "dwifi,dbt,dnd,cell,battery,user,rotation,flashlight,location,"
-             + "hotspot,qwifi,qbt,qlock,qflashlight,qairplane,inversion,cast";
+            "dnd,cell,battery,user,rotation,flashlight,location,"
+             + "hotspot,inversion,cast";
 
     public QSPagingSwitch(Context context, AttributeSet attrs) {
         super(context, attrs);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 11fdbb5..8cf25b3 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -3987,6 +3987,9 @@
         private final Uri mDisplayDaltonizerUri = Settings.Secure.getUriFor(
                 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER);
 
+        private final Uri mDisplayColorMatrixUri = Settings.Secure.getUriFor(
+                Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX);
+
         private final Uri mHighTextContrastUri = Settings.Secure.getUriFor(
                 Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED);
 
@@ -4017,6 +4020,8 @@
             contentResolver.registerContentObserver(
                     mDisplayDaltonizerUri, false, this, UserHandle.USER_ALL);
             contentResolver.registerContentObserver(
+                    mDisplayColorMatrixUri, false, this, UserHandle.USER_ALL);
+            contentResolver.registerContentObserver(
                     mHighTextContrastUri, false, this, UserHandle.USER_ALL);
         }
 
@@ -4066,6 +4071,8 @@
                     if (readDisplayColorAdjustmentSettingsLocked(userState)) {
                         updateDisplayColorAdjustmentSettingsLocked(userState);
                     }
+                } else if (mDisplayColorMatrixUri.equals(uri)) {
+                    updateDisplayColorAdjustmentSettingsLocked(userState);
                 } else if (mHighTextContrastUri.equals(uri)) {
                     if (readHighTextContrastEnabledSettingLocked(userState)) {
                         onUserStateChangedLocked(userState);
diff --git a/services/accessibility/java/com/android/server/accessibility/DisplayAdjustmentUtils.java b/services/accessibility/java/com/android/server/accessibility/DisplayAdjustmentUtils.java
index d0b5898..1a7de25 100644
--- a/services/accessibility/java/com/android/server/accessibility/DisplayAdjustmentUtils.java
+++ b/services/accessibility/java/com/android/server/accessibility/DisplayAdjustmentUtils.java
@@ -107,9 +107,24 @@
             setDaltonizerMode(AccessibilityManager.DALTONIZER_DISABLED);
         }
 
+        String matrix = Settings.Secure.getStringForUser(cr,
+                Settings.Secure.ACCESSIBILITY_DISPLAY_COLOR_MATRIX, userId);
+        if (matrix != null) {
+            colorMatrix = multiply(colorMatrix, getMatrix(matrix));
+        }
+
         setColorTransform(colorMatrix);
     }
 
+    private static float[] getMatrix(String matrix) {
+        String[] strValues = matrix.split(",");
+        float[] values = new float[strValues.length];
+        for (int i = 0; i < values.length; i++) {
+            values[i] = Float.parseFloat(strValues[i]);
+        }
+        return values;
+    }
+
     private static float[] multiply(float[] matrix, float[] other) {
         if (matrix == null) {
             return other;
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index f6af942..5f57a76 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -1233,14 +1233,6 @@
                 }
             }
 
-            // direct-callback alarms must be wakeup alarms (otherwise they should just be
-            // posting work to a Handler)
-            if (directReceiver != null) {
-                if (type != RTC_WAKEUP && type != ELAPSED_REALTIME_WAKEUP) {
-                    throw new IllegalArgumentException("Only wakeup alarms can use AlarmReceivers");
-                }
-            }
-
             if (workSource != null) {
                 getContext().enforcePermission(
                         android.Manifest.permission.UPDATE_DEVICE_STATS,
@@ -1363,7 +1355,7 @@
 
             pw.print("  nowRTC="); pw.print(nowRTC);
             pw.print("="); pw.print(sdf.format(new Date(nowRTC)));
-            pw.print(" nowELAPSED="); TimeUtils.formatDuration(nowELAPSED, pw);
+            pw.print(" nowELAPSED="); pw.print(nowELAPSED);
             pw.println();
             pw.print("  mLastTimeChangeClockTime="); pw.print(mLastTimeChangeClockTime);
             pw.print("="); pw.println(sdf.format(new Date(mLastTimeChangeClockTime)));
@@ -1464,6 +1456,15 @@
             pw.print("  Broadcast ref count: "); pw.println(mBroadcastRefCount);
             pw.println();
 
+            if (mInFlight.size() > 0) {
+                pw.println("Outstanding deliveries:");
+                for (int i = 0; i < mInFlight.size(); i++) {
+                    pw.print("   #"); pw.print(i); pw.print(": ");
+                    pw.println(mInFlight.get(i));
+                }
+                pw.println();
+            }
+
             pw.print("  mAllowWhileIdleMinTime=");
             TimeUtils.formatDuration(mAllowWhileIdleMinTime, pw);
             pw.println();
@@ -2956,6 +2957,11 @@
                         // is a repeating alarm, so toss it
                         removeImpl(alarm.operation);
                     }
+                    // No actual delivery was possible, so the delivery tracker's
+                    // 'finished' callback won't be invoked.  We also don't need
+                    // to do any wakelock or stats tracking, so we have nothing
+                    // left to do here but go on to the next thing.
+                    return;
                 }
             } else {
                 // Direct listener callback alarm
@@ -2974,6 +2980,11 @@
                         Slog.i(TAG, "Alarm undeliverable to listener "
                                 + alarm.listener.asBinder(), e);
                     }
+                    // As in the PendingIntent.CanceledException case, delivery of the
+                    // alarm was not possible, so we have no wakelock or timeout or
+                    // stats management to do.  It threw before we posted the delayed
+                    // timeout message, so we're done here.
+                    return;
                 }
             }
 
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index ede92fb..353b404 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -788,6 +788,9 @@
 
     @Override
     public void startWatchingMode(int op, String packageName, IAppOpsCallback callback) {
+        if (callback == null) {
+            return;
+        }
         synchronized (this) {
             op = (op != AppOpsManager.OP_NONE) ? AppOpsManager.opToSwitch(op) : op;
             Callback cb = mModeWatchers.get(callback.asBinder());
@@ -816,6 +819,9 @@
 
     @Override
     public void stopWatchingMode(IAppOpsCallback callback) {
+        if (callback == null) {
+            return;
+        }
         synchronized (this) {
             Callback cb = mModeWatchers.remove(callback.asBinder());
             if (cb != null) {
@@ -1170,6 +1176,9 @@
                             if ("media".equals(packageName)) {
                                 pkgUid = Process.MEDIA_UID;
                                 isPrivileged = false;
+                            } else if ("audioserver".equals(packageName)) {
+                                pkgUid = Process.AUDIOSERVER_UID;
+                                isPrivileged = false;
                             }
                         }
                     } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index c712a56..ed64c2b 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -34,6 +34,7 @@
 
 import android.annotation.Nullable;
 import android.app.AlarmManager;
+import android.app.BroadcastOptions;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -72,6 +73,7 @@
 import android.net.UidRange;
 import android.net.Uri;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.FileUtils;
 import android.os.Handler;
@@ -1529,6 +1531,7 @@
                 log("sendStickyBroadcast: action=" + intent.getAction());
             }
 
+            Bundle options = null;
             final long ident = Binder.clearCallingIdentity();
             if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
                 final NetworkInfo ni = intent.getParcelableExtra(
@@ -1536,6 +1539,10 @@
                 if (ni.getType() == ConnectivityManager.TYPE_MOBILE_SUPL) {
                     intent.setAction(ConnectivityManager.CONNECTIVITY_ACTION_SUPL);
                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+                } else {
+                    BroadcastOptions opts = BroadcastOptions.makeBasic();
+                    opts.setMaxManifestReceiverApiLevel(Build.VERSION_CODES.M);
+                    options = opts.toBundle();
                 }
                 final IBatteryStats bs = BatteryStatsService.getService();
                 try {
@@ -1546,7 +1553,7 @@
                 }
             }
             try {
-                mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+                mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL, options);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 42dd9a8..ef79cfe 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -43,11 +43,11 @@
 import android.app.AlertDialog;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
-import android.app.IUserSwitchObserver;
 import android.app.KeyguardManager;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
+import android.app.SynchronousUserSwitchObserver;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -80,7 +80,6 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.IInterface;
-import android.os.IRemoteCallback;
 import android.os.Message;
 import android.os.Parcel;
 import android.os.Process;
@@ -788,18 +787,13 @@
         int userId = 0;
         try {
             ActivityManagerNative.getDefault().registerUserSwitchObserver(
-                    new IUserSwitchObserver.Stub() {
+                    new SynchronousUserSwitchObserver() {
                         @Override
-                        public void onUserSwitching(int newUserId, IRemoteCallback reply) {
+                        public void onUserSwitching(int newUserId)
+                                throws RemoteException {
                             synchronized(mMethodMap) {
                                 switchUserLocked(newUserId);
                             }
-                            if (reply != null) {
-                                try {
-                                    reply.sendResult(null);
-                                } catch (RemoteException e) {
-                                }
-                            }
                         }
 
                         @Override
@@ -3033,7 +3027,7 @@
 
             final List<ImeSubtypeListItem> imList =
                     mSwitchingController.getSortedInputMethodAndSubtypeListLocked(
-                            true /* showSubtypes */, showAuxSubtypes, isScreenLocked);
+                            showAuxSubtypes, isScreenLocked);
 
             if (lastInputMethodSubtypeId == NOT_A_SUBTYPE_ID) {
                 final InputMethodSubtype currentSubtype = getCurrentInputMethodSubtypeLocked();
@@ -3542,6 +3536,7 @@
         private static final String ATTR_LABEL = "label";
         private static final String ATTR_ICON = "icon";
         private static final String ATTR_IME_SUBTYPE_LOCALE = "imeSubtypeLocale";
+        private static final String ATTR_IME_SUBTYPE_LANGUAGE_TAG = "languageTag";
         private static final String ATTR_IME_SUBTYPE_MODE = "imeSubtypeMode";
         private static final String ATTR_IME_SUBTYPE_EXTRA_VALUE = "imeSubtypeExtraValue";
         private static final String ATTR_IS_AUXILIARY = "isAuxiliary";
@@ -3635,6 +3630,8 @@
                         out.attribute(null, ATTR_ICON, String.valueOf(subtype.getIconResId()));
                         out.attribute(null, ATTR_LABEL, String.valueOf(subtype.getNameResId()));
                         out.attribute(null, ATTR_IME_SUBTYPE_LOCALE, subtype.getLocale());
+                        out.attribute(null, ATTR_IME_SUBTYPE_LANGUAGE_TAG,
+                                subtype.getLanguageTag());
                         out.attribute(null, ATTR_IME_SUBTYPE_MODE, subtype.getMode());
                         out.attribute(null, ATTR_IME_SUBTYPE_EXTRA_VALUE, subtype.getExtraValue());
                         out.attribute(null, ATTR_IS_AUXILIARY,
@@ -3696,6 +3693,8 @@
                                 parser.getAttributeValue(null, ATTR_LABEL));
                         final String imeSubtypeLocale =
                                 parser.getAttributeValue(null, ATTR_IME_SUBTYPE_LOCALE);
+                        final String languageTag =
+                                parser.getAttributeValue(null, ATTR_IME_SUBTYPE_LANGUAGE_TAG);
                         final String imeSubtypeMode =
                                 parser.getAttributeValue(null, ATTR_IME_SUBTYPE_MODE);
                         final String imeSubtypeExtraValue =
@@ -3706,6 +3705,7 @@
                                 .setSubtypeNameResId(label)
                                 .setSubtypeIconResId(icon)
                                 .setSubtypeLocale(imeSubtypeLocale)
+                                .setLanguageTag(languageTag)
                                 .setSubtypeMode(imeSubtypeMode)
                                 .setSubtypeExtraValue(imeSubtypeExtraValue)
                                 .setIsAuxiliary(isAuxiliary)
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 807c0d6..184f890 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -57,6 +57,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
+import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
@@ -175,8 +176,8 @@
         }
 
         @Override
-        public void onStartUser(int userHandle) {
-            mMountService.onStartUser(userHandle);
+        public void onUnlockUser(int userHandle) {
+            mMountService.onUnlockUser(userHandle);
         }
 
         @Override
@@ -286,10 +287,12 @@
      */
     private final Object mLock = new Object();
 
+    /** Set of users that we know are unlocked. */
     @GuardedBy("mLock")
-    private int[] mStartedUsers = EmptyArray.INT;
+    private int[] mLocalUnlockedUsers = EmptyArray.INT;
+    /** Set of users that system knows are unlocked. */
     @GuardedBy("mLock")
-    private int[] mUnlockedUsers = EmptyArray.INT;
+    private int[] mSystemUnlockedUsers = EmptyArray.INT;
 
     /** Map from disk ID to disk */
     @GuardedBy("mLock")
@@ -834,12 +837,21 @@
     private void initIfReadyAndConnected() {
         Slog.d(TAG, "Thinking about init, mSystemReady=" + mSystemReady
                 + ", mDaemonConnected=" + mDaemonConnected);
-        if (mSystemReady && mDaemonConnected && StorageManager.isFileBasedEncryptionEnabled()) {
-            final List<UserInfo> users = mContext.getSystemService(UserManager.class)
-                    .getUsers();
+        if (mSystemReady && mDaemonConnected
+                && !StorageManager.isNativeFileBasedEncryptionEnabled()) {
+            // When booting a device without native support, make sure that our
+            // user directories are locked or unlocked based on the current
+            // emulation status.
+            final boolean initLocked = StorageManager.isEmulatedFileBasedEncryptionEnabled();
+            final List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
             for (UserInfo user : users) {
                 try {
-                    mCryptConnector.execute("cryptfs", "lock_user_key", user.id);
+                    if (initLocked) {
+                        mCryptConnector.execute("cryptfs", "lock_user_key", user.id);
+                    } else {
+                        mCryptConnector.execute("cryptfs", "unlock_user_key", user.id,
+                                user.serialNumber, "!");
+                    }
                 } catch (NativeDaemonConnectorException e) {
                     Slog.w(TAG, "Failed to init vold", e);
                 }
@@ -854,9 +866,9 @@
             final List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
             killMediaProvider(users);
 
-            final int[] startedUsers;
+            final int[] systemUnlockedUsers;
             synchronized (mLock) {
-                startedUsers = mStartedUsers;
+                systemUnlockedUsers = mSystemUnlockedUsers;
 
                 mDisks.clear();
                 mVolumes.clear();
@@ -871,7 +883,7 @@
                 for (UserInfo user : users) {
                     mConnector.execute("volume", "user_added", user.id, user.serialNumber);
                 }
-                for (int userId : startedUsers) {
+                for (int userId : systemUnlockedUsers) {
                     mConnector.execute("volume", "user_started", userId);
                 }
             } catch (NativeDaemonConnectorException e) {
@@ -880,8 +892,8 @@
         }
     }
 
-    private void onStartUser(int userId) {
-        Slog.d(TAG, "onStartUser " + userId);
+    private void onUnlockUser(int userId) {
+        Slog.d(TAG, "onUnlockUser " + userId);
 
         // We purposefully block here to make sure that user-specific
         // staging area is ready so it's ready for zygote-forked apps to
@@ -904,7 +916,7 @@
                     mCallbacks.notifyStorageStateChanged(userVol.getPath(), envState, envState);
                 }
             }
-            mStartedUsers = ArrayUtils.appendInt(mStartedUsers, userId);
+            mSystemUnlockedUsers = ArrayUtils.appendInt(mSystemUnlockedUsers, userId);
         }
     }
 
@@ -917,7 +929,7 @@
         }
 
         synchronized (mVolumes) {
-            mStartedUsers = ArrayUtils.removeInt(mStartedUsers, userId);
+            mSystemUnlockedUsers = ArrayUtils.removeInt(mSystemUnlockedUsers, userId);
         }
     }
 
@@ -1337,7 +1349,7 @@
             // Kick state changed event towards all started users. Any users
             // started after this point will trigger additional
             // user-specific broadcasts.
-            for (int userId : mStartedUsers) {
+            for (int userId : mSystemUnlockedUsers) {
                 if (vol.isVisibleForRead(userId)) {
                     final StorageVolume userVol = vol.buildStorageVolume(mContext, userId, false);
                     mHandler.obtainMessage(H_VOLUME_BROADCAST, userVol).sendToTarget();
@@ -1926,8 +1938,16 @@
         waitForReady();
 
         if ((mask & StorageManager.DEBUG_EMULATE_FBE) != 0) {
+            if (StorageManager.isNativeFileBasedEncryptionEnabled()) {
+                throw new IllegalStateException(
+                        "Emulation not available on device with native FBE");
+            }
+
             final boolean emulateFbe = (flags & StorageManager.DEBUG_EMULATE_FBE) != 0;
             SystemProperties.set(StorageManager.PROP_EMULATE_FBE, Boolean.toString(emulateFbe));
+
+            // Perform hard reboot to kick policy into place
+            mContext.getSystemService(PowerManager.class).reboot(null);
         }
 
         if ((mask & StorageManager.DEBUG_FORCE_ADOPTABLE) != 0) {
@@ -2696,12 +2716,13 @@
     }
 
     @Override
-    public void createUserKey(int userId, int serialNumber) {
+    public void createUserKey(int userId, int serialNumber, boolean ephemeral) {
         enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
         waitForReady();
 
         try {
-            mCryptConnector.execute("cryptfs", "create_user_key", userId, serialNumber);
+            mCryptConnector.execute("cryptfs", "create_user_key", userId, serialNumber,
+                ephemeral ? 1 : 0);
         } catch (NativeDaemonConnectorException e) {
             throw e.rethrowAsParcelableException();
         }
@@ -2745,7 +2766,7 @@
         }
 
         synchronized (mLock) {
-            mUnlockedUsers = ArrayUtils.appendInt(mUnlockedUsers, userId);
+            mLocalUnlockedUsers = ArrayUtils.appendInt(mLocalUnlockedUsers, userId);
         }
     }
 
@@ -2761,7 +2782,7 @@
         }
 
         synchronized (mLock) {
-            mUnlockedUsers = ArrayUtils.removeInt(mUnlockedUsers, userId);
+            mLocalUnlockedUsers = ArrayUtils.removeInt(mLocalUnlockedUsers, userId);
         }
     }
 
@@ -2769,7 +2790,7 @@
     public boolean isUserKeyUnlocked(int userId) {
         if (StorageManager.isFileBasedEncryptionEnabled()) {
             synchronized (mLock) {
-                return ArrayUtils.contains(mUnlockedUsers, userId);
+                return ArrayUtils.contains(mLocalUnlockedUsers, userId);
             }
         } else {
             return true;
@@ -2777,13 +2798,14 @@
     }
 
     @Override
-    public void prepareUserStorage(String volumeUuid, int userId, int serialNumber) {
+    public void prepareUserStorage(
+            String volumeUuid, int userId, int serialNumber, boolean ephemeral) {
         enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
         waitForReady();
 
         try {
             mCryptConnector.execute("cryptfs", "prepare_user_storage", escapeNull(volumeUuid),
-                    userId, serialNumber);
+                    userId, serialNumber, ephemeral ? 1 : 0);
         } catch (NativeDaemonConnectorException e) {
             throw e.rethrowAsParcelableException();
         }
@@ -2836,21 +2858,25 @@
 
     @Override
     public StorageVolume[] getVolumeList(int uid, String packageName, int flags) {
+        final int userId = UserHandle.getUserId(uid);
         final boolean forWrite = (flags & StorageManager.FLAG_FOR_WRITE) != 0;
 
-        final ArrayList<StorageVolume> res = new ArrayList<>();
+        boolean reportUnmounted = false;
         boolean foundPrimary = false;
 
-        final int userId = UserHandle.getUserId(uid);
-        final boolean reportUnmounted;
         final long identity = Binder.clearCallingIdentity();
         try {
-            reportUnmounted = !mMountServiceInternal.hasExternalStorage(
-                    uid, packageName);
+            if (!mMountServiceInternal.hasExternalStorage(uid, packageName)) {
+                reportUnmounted = true;
+            }
+            if (!isUserKeyUnlocked(userId)) {
+                reportUnmounted = true;
+            }
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
 
+        final ArrayList<StorageVolume> res = new ArrayList<>();
         synchronized (mLock) {
             for (int i = 0; i < mVolumes.size(); i++) {
                 final VolumeInfo vol = mVolumes.valueAt(i);
@@ -3530,8 +3556,8 @@
             pw.println("Primary storage UUID: " + mPrimaryStorageUuid);
             pw.println("Force adoptable: " + mForceAdoptable);
             pw.println();
-            pw.println("Started users: " + Arrays.toString(mStartedUsers));
-            pw.println("Unlocked users: " + Arrays.toString(mUnlockedUsers));
+            pw.println("Local unlocked users: " + Arrays.toString(mLocalUnlockedUsers));
+            pw.println("System unlocked users: " + Arrays.toString(mSystemUnlockedUsers));
         }
 
         synchronized (mObbMounts) {
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index fcd56eb7..c4b4cbe 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -29,7 +29,7 @@
 
 import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
-import android.app.IUserSwitchObserver;
+import android.app.SynchronousUserSwitchObserver;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -45,7 +45,6 @@
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
-import android.os.IRemoteCallback;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -102,18 +101,12 @@
         int userId = UserHandle.USER_SYSTEM;
         try {
             ActivityManagerNative.getDefault().registerUserSwitchObserver(
-                    new IUserSwitchObserver.Stub() {
+                    new SynchronousUserSwitchObserver() {
                         @Override
-                        public void onUserSwitching(int newUserId, IRemoteCallback reply) {
+                        public void onUserSwitching(int newUserId) throws RemoteException {
                             synchronized(mSpellCheckerMap) {
                                 switchUserLocked(newUserId);
                             }
-                            if (reply != null) {
-                                try {
-                                    reply.sendResult(null);
-                                } catch (RemoteException e) {
-                                }
-                            }
                         }
 
                         @Override
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 2742c65..4348913 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -1240,8 +1240,9 @@
                     try {
                         // Before going further -- if this app is not allowed to run in the
                         // background, then at this point we aren't going to let it period.
-                        if (!mAm.checkAllowBackgroundLocked(sInfo.applicationInfo.uid,
-                                sInfo.packageName, callingPid)) {
+                        final int allowed = mAm.checkAllowBackgroundLocked(
+                                sInfo.applicationInfo.uid, sInfo.packageName, callingPid);
+                        if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
                             Slog.w(TAG, "Background execution not allowed: service "
                                     + r.intent + " to " + name.flattenToShortString()
                                     + " from pid=" + callingPid + " uid=" + callingUid
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7d768bd..9a185bb 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -490,6 +490,8 @@
 
     // Used to indicate that a task is removed it should also be removed from recents.
     private static final boolean REMOVE_FROM_RECENTS = true;
+    // Used to indicate that an app transition should be animated.
+    private static final boolean ANIMATE = true;
 
     private static native int nativeMigrateToBoost();
     private static native int nativeMigrateFromBoost();
@@ -3484,27 +3486,29 @@
                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
             }
 
-            checkTime(startTime, "startProcess: building log message");
-            StringBuilder buf = mStringBuilder;
-            buf.setLength(0);
-            buf.append("Start proc ");
-            buf.append(startResult.pid);
-            buf.append(':');
-            buf.append(app.processName);
-            buf.append('/');
-            UserHandle.formatUid(buf, uid);
-            if (!isActivityProcess) {
-                buf.append(" [");
-                buf.append(entryPoint);
-                buf.append("]");
+            if (DEBUG_PROCESSES) {
+                checkTime(startTime, "startProcess: building log message");
+                StringBuilder buf = mStringBuilder;
+                buf.setLength(0);
+                buf.append("Start proc ");
+                buf.append(startResult.pid);
+                buf.append(':');
+                buf.append(app.processName);
+                buf.append('/');
+                UserHandle.formatUid(buf, uid);
+                if (!isActivityProcess) {
+                    buf.append(" [");
+                    buf.append(entryPoint);
+                    buf.append("]");
+                }
+                buf.append(" for ");
+                buf.append(hostingType);
+                if (hostingNameStr != null) {
+                    buf.append(" ");
+                    buf.append(hostingNameStr);
+                }
+                Slog.i(TAG, buf.toString());
             }
-            buf.append(" for ");
-            buf.append(hostingType);
-            if (hostingNameStr != null) {
-                buf.append(" ");
-                buf.append(hostingNameStr);
-            }
-            Slog.i(TAG, buf.toString());
             app.setPid(startResult.pid);
             app.usingWrapper = startResult.usingWrapper;
             app.removed = false;
@@ -4331,7 +4335,7 @@
                 if (task.stack.mStackId != launchStackId) {
                     mStackSupervisor.moveTaskToStackLocked(
                             taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
-                            true /* animate */);
+                            ANIMATE);
                 }
             }
 
@@ -7463,13 +7467,11 @@
 
     public int getAppStartMode(int uid, String packageName) {
         synchronized (this) {
-            boolean bg = checkAllowBackgroundLocked(uid, packageName, -1);
-            return bg ? ActivityManager.APP_START_MODE_NORMAL
-                    : ActivityManager.APP_START_MODE_DISABLED;
+            return checkAllowBackgroundLocked(uid, packageName, -1);
         }
     }
 
-    boolean checkAllowBackgroundLocked(int uid, String packageName, int callingPid) {
+    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid) {
         UidRecord uidRec = mActiveUids.get(uid);
         if (uidRec == null || uidRec.idle) {
             if (callingPid >= 0) {
@@ -7480,15 +7482,15 @@
                 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
                     // Whoever is instigating this is in the foreground, so we will allow it
                     // to go through.
-                    return true;
+                    return ActivityManager.APP_START_MODE_NORMAL;
                 }
             }
             if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
                     != AppOpsManager.MODE_ALLOWED) {
-                return false;
+                return ActivityManager.APP_START_MODE_DELAYED;
             }
         }
-        return true;
+        return ActivityManager.APP_START_MODE_NORMAL;
     }
 
     private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
@@ -9314,7 +9316,7 @@
                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveActivityToStack: moving r=" + r
                         + " to stackId=" + stackId);
                 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, stackId, ON_TOP, !FORCE_FOCUS,
-                        "moveActivityToStack", true /* animate */);
+                        "moveActivityToStack", ANIMATE);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -9335,7 +9337,7 @@
                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
                         + " to stackId=" + stackId + " toTop=" + toTop);
                 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
-                        "moveTaskToStack", true /* animate */);
+                        "moveTaskToStack", ANIMATE);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -11191,9 +11193,10 @@
         }
     }
 
-    public void requestBugReport() {
+    public void requestBugReport(boolean progress) {
+        final String service = progress ? "bugreportplus" : "bugreport";
         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
-        SystemProperties.set("ctl.start", "bugreport");
+        SystemProperties.set("ctl.start", service);
     }
 
     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
@@ -16999,6 +17002,15 @@
             }
         }
 
+        final String action = intent.getAction();
+        final boolean isProtectedBroadcast;
+        try {
+            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
+        } catch (RemoteException e) {
+            Slog.w(TAG, "Remote exception", e);
+            return ActivityManager.BROADCAST_SUCCESS;
+        }
+
         /*
          * Prevent non-system code (defined here to be non-persistent
          * processes) from sending protected broadcasts.
@@ -17008,49 +17020,54 @@
             || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
             || callingAppId == Process.NFC_UID || callingUid == 0) {
             // Always okay.
+
+            // Yell if the system is trying to send a non-protected broadcast.
+            // The vast majority of broadcasts sent from system callers should
+            // be protected to avoid security holes, so exceptions here should
+            // be incredibly rare.
+            if (!isProtectedBroadcast
+                    && !Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
+                // TODO: eventually switch over to hard throw
+                Log.wtf(TAG, "Sending non-protected broadcast " + action
+                        + " from system", new Throwable());
+            }
+
         } else if (callerApp == null || !callerApp.persistent) {
-            try {
-                if (AppGlobals.getPackageManager().isProtectedBroadcast(
-                        intent.getAction())) {
+            if (isProtectedBroadcast) {
+                String msg = "Permission Denial: not allowed to send broadcast "
+                        + action + " from pid="
+                        + callingPid + ", uid=" + callingUid;
+                Slog.w(TAG, msg);
+                throw new SecurityException(msg);
+            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)) {
+                // Special case for compatibility: we don't want apps to send this,
+                // but historically it has not been protected and apps may be using it
+                // to poke their own app widget.  So, instead of making it protected,
+                // just limit it to the caller.
+                if (callerApp == null) {
                     String msg = "Permission Denial: not allowed to send broadcast "
-                            + intent.getAction() + " from pid="
-                            + callingPid + ", uid=" + callingUid;
+                            + action + " from unknown caller.";
                     Slog.w(TAG, msg);
                     throw new SecurityException(msg);
-                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
-                    // Special case for compatibility: we don't want apps to send this,
-                    // but historically it has not been protected and apps may be using it
-                    // to poke their own app widget.  So, instead of making it protected,
-                    // just limit it to the caller.
-                    if (callerApp == null) {
+                } else if (intent.getComponent() != null) {
+                    // They are good enough to send to an explicit component...  verify
+                    // it is being sent to the calling app.
+                    if (!intent.getComponent().getPackageName().equals(
+                            callerApp.info.packageName)) {
                         String msg = "Permission Denial: not allowed to send broadcast "
-                                + intent.getAction() + " from unknown caller.";
+                                + action + " to "
+                                + intent.getComponent().getPackageName() + " from "
+                                + callerApp.info.packageName;
                         Slog.w(TAG, msg);
                         throw new SecurityException(msg);
-                    } else if (intent.getComponent() != null) {
-                        // They are good enough to send to an explicit component...  verify
-                        // it is being sent to the calling app.
-                        if (!intent.getComponent().getPackageName().equals(
-                                callerApp.info.packageName)) {
-                            String msg = "Permission Denial: not allowed to send broadcast "
-                                    + intent.getAction() + " to "
-                                    + intent.getComponent().getPackageName() + " from "
-                                    + callerApp.info.packageName;
-                            Slog.w(TAG, msg);
-                            throw new SecurityException(msg);
-                        }
-                    } else {
-                        // Limit broadcast to their own package.
-                        intent.setPackage(callerApp.info.packageName);
                     }
+                } else {
+                    // Limit broadcast to their own package.
+                    intent.setPackage(callerApp.info.packageName);
                 }
-            } catch (RemoteException e) {
-                Slog.w(TAG, "Remote exception", e);
-                return ActivityManager.BROADCAST_SUCCESS;
             }
         }
 
-        final String action = intent.getAction();
         if (action != null) {
             switch (action) {
                 case Intent.ACTION_UID_REMOVED:
@@ -17764,20 +17781,20 @@
     }
 
     @Override
-    public void removeStack(int stackId) {
+    public void moveTasksToFullscreenStack(int fromStackId) {
         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
-                "detahStack()");
-        if (stackId == HOME_STACK_ID) {
-            throw new IllegalArgumentException("Removing home stack is not allowed.");
+                "moveTasksToFullscreenStack()");
+        if (fromStackId == HOME_STACK_ID) {
+            throw new IllegalArgumentException("You can't move tasks from the home stack.");
         }
         synchronized (this) {
-            long origId = Binder.clearCallingIdentity();
-            ActivityStack stack = mStackSupervisor.getStack(stackId);
+            final long origId = Binder.clearCallingIdentity();
+            final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
             if (stack != null) {
-                ArrayList<TaskRecord> tasks = stack.getAllTasks();
+                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
                 for (int i = tasks.size() - 1; i >= 0; i--) {
-                    removeTaskByIdLocked(tasks.get(i).taskId, false /* killProcess */,
-                            !REMOVE_FROM_RECENTS);
+                    mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId,
+                            FULLSCREEN_WORKSPACE_STACK_ID, 0);
                 }
             }
             Binder.restoreCallingIdentity(origId);
@@ -17888,7 +17905,7 @@
                     if (mSupportedSystemLocales == null) {
                         mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
                     }
-                    final Locale locale = values.getLocales().getBestMatch(mSupportedSystemLocales);
+                    final Locale locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
                     SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
                     mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
                             locale));
@@ -19735,7 +19752,7 @@
                         } else {
                             numEmpty++;
                             if (numEmpty > emptyProcessLimit) {
-                                app.kill("empty #" + numEmpty, true);
+                                app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
                             }
                         }
                         break;
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 66371d1..d215fc6 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -180,6 +180,7 @@
     private boolean inHistory;  // are we in the history stack?
     final ActivityStackSupervisor mStackSupervisor;
     boolean mStartingWindowShown = false;
+    boolean mUpdateTaskThumbnailWhenHidden;
     ActivityContainer mInitialActivityContainer;
 
     TaskDescription taskDescription; // the recents information for this activity
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index bad71b2..b6fc0cc 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -74,6 +74,7 @@
 import android.os.UserHandle;
 import android.service.voice.IVoiceInteractionSession;
 import android.util.EventLog;
+import android.util.Log;
 import android.util.Slog;
 import android.view.Display;
 
@@ -145,6 +146,9 @@
     // convertToTranslucent().
     static final long TRANSLUCENT_CONVERSION_TIMEOUT = 2000;
 
+    // How many activities have to be scheduled to stop to force a stop pass.
+    private static final int MAX_STOPPING_TO_FORCE = 3;
+
     enum ActivityState {
         INITIALIZING,
         RESUMED,
@@ -730,7 +734,7 @@
                 "Launch completed; removing icicle of " + r.icicle);
     }
 
-    private void addRecentActivityLocked(ActivityRecord r) {
+    void addRecentActivityLocked(ActivityRecord r) {
         if (r != null) {
             mRecentTasks.addLocked(r.task);
             r.task.touchActiveTime();
@@ -922,7 +926,7 @@
         final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
         if (mService.mHasRecents
                 && (next == null || next.noDisplay || next.task != prev.task || uiSleeping)) {
-            prev.updateThumbnailLocked(screenshotActivitiesLocked(prev), null);
+            prev.mUpdateTaskThumbnailWhenHidden = true;
         }
         stopFullyDrawnTraceIfNeeded();
 
@@ -1097,19 +1101,7 @@
                 } else if (!hasVisibleBehindActivity() || mService.isSleepingOrShuttingDown()) {
                     // If we were visible then resumeTopActivities will release resources before
                     // stopping.
-
-                    mStackSupervisor.mStoppingActivities.add(prev);
-                    if (mStackSupervisor.mStoppingActivities.size() > 3 ||
-                            prev.frontOfTask && mTaskHistory.size() <= 1) {
-                        // If we already have a few activities waiting to stop,
-                        // then give up on things going idle and start clearing
-                        // them out. Or if r is the last of activity of the last task the stack
-                        // will be empty and must be cleared immediately.
-                        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "To many pending stops, forcing idle");
-                        mStackSupervisor.scheduleIdleLocked();
-                    } else {
-                        mStackSupervisor.checkReadyForSleepLocked();
-                    }
+                    addToStopping(prev);
                 }
             } else {
                 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
@@ -1166,6 +1158,21 @@
         mService.notifyTaskStackChangedLocked();
     }
 
+    private void addToStopping(ActivityRecord r) {
+        mStackSupervisor.mStoppingActivities.add(r);
+        if (mStackSupervisor.mStoppingActivities.size() > MAX_STOPPING_TO_FORCE ||
+                r.frontOfTask && mTaskHistory.size() <= 1) {
+            // If we already have a few activities waiting to stop,
+            // then give up on things going idle and start clearing
+            // them out. Or if r is the last of activity of the last task the stack
+            // will be empty and must be cleared immediately.
+            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "To many pending stops, forcing idle");
+            mStackSupervisor.scheduleIdleLocked();
+        } else {
+            mStackSupervisor.checkReadyForSleepLocked();
+        }
+    }
+
     /**
      * Once we know that we have asked an application to put an activity in
      * the resumed state (either by launching it or explicitly telling it),
@@ -1215,6 +1222,10 @@
 
     private void setVisible(ActivityRecord r, boolean visible) {
         r.visible = visible;
+        if (!visible && r.mUpdateTaskThumbnailWhenHidden) {
+            r.updateThumbnailLocked(r.task.stack.screenshotActivitiesLocked(r), null);
+            r.mUpdateTaskThumbnailWhenHidden = false;
+        }
         mWindowManager.setAppVisibility(r.appToken, visible);
         final ArrayList<ActivityContainer> containers = r.mChildContainers;
         for (int containerNdx = containers.size() - 1; containerNdx >= 0; --containerNdx) {
@@ -1348,6 +1359,13 @@
         final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
         final int focusedStackId = focusedStack.mStackId;
 
+        if (mStackId == FULLSCREEN_WORKSPACE_STACK_ID
+                && hasVisibleBehindActivity() && focusedStackId == HOME_STACK_ID) {
+            // The fullscreen stack should be visible if it has a visible behind activity behind
+            // the home stack that will be translucent.
+            return true;
+        }
+
         if (mStackId == DOCKED_STACK_ID) {
             // Docked stack is always visible, except in the case where the home activity
             // is the top running activity in the focused home stack.
@@ -2302,8 +2320,8 @@
         updateTaskMovement(task, true);
     }
 
-    final void startActivityLocked(ActivityRecord r, boolean newTask,
-            boolean doResume, boolean keepCurTransition, ActivityOptions options) {
+    final void startActivityLocked(ActivityRecord r, boolean newTask, boolean keepCurTransition,
+            ActivityOptions options) {
         TaskRecord rTask = r.task;
         final int taskId = rTask.taskId;
         // mLaunchTaskBehind tasks get placed at the back of the task stack.
@@ -2449,12 +2467,6 @@
         if (VALIDATE_TOKENS) {
             validateAppTokensLocked();
         }
-
-        if (doResume) {
-            mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
-        } else {
-            addRecentActivityLocked(r);
-        }
     }
 
     final void validateAppTokensLocked() {
@@ -3167,17 +3179,7 @@
         // finishing until the resumed one becomes visible.
         if (mode == FINISH_AFTER_VISIBLE && r.nowVisible) {
             if (!mStackSupervisor.mStoppingActivities.contains(r)) {
-                mStackSupervisor.mStoppingActivities.add(r);
-                if (mStackSupervisor.mStoppingActivities.size() > 3
-                        || r.frontOfTask && mTaskHistory.size() <= 1) {
-                    // If we already have a few activities waiting to stop,
-                    // then give up on things going idle and start clearing
-                    // them out. Or if r is the last of activity of the last task the stack
-                    // will be empty and must be cleared immediately.
-                    mStackSupervisor.scheduleIdleLocked();
-                } else {
-                    mStackSupervisor.checkReadyForSleepLocked();
-                }
+                addToStopping(r);
             }
             if (DEBUG_STATES) Slog.v(TAG_STATES,
                     "Moving to STOPPING: "+ r + " (finish requested)");
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index f4ba19f..9fff0c8 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2628,9 +2628,14 @@
         }
         ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
         targetStack.mLastPausedActivity = null;
-        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
-        if (!launchTaskBehind && doResume) {
-            mService.setFocusedActivityLocked(r, "startedActivity");
+        targetStack.startActivityLocked(r, newTask, keepCurTransition, options);
+        if (doResume) {
+            if (!launchTaskBehind) {
+                mService.setFocusedActivityLocked(r, "startedActivity");
+            }
+            resumeTopActivitiesLocked(targetStack, r, options);
+        } else {
+            targetStack.addRecentActivityLocked(r);
         }
         updateUserStackLocked(r.userId, targetStack);
 
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index b160981..622aa16 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -468,7 +468,7 @@
     }
 
     private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
-            BroadcastFilter filter, boolean ordered) {
+            BroadcastFilter filter, boolean ordered, int index) {
         boolean skip = false;
         if (filter.requiredPermission != null) {
             int perm = mService.checkComponentPermission(filter.requiredPermission,
@@ -562,8 +562,9 @@
             skip = true;
         }
         if (!skip) {
-            if (!mService.checkAllowBackgroundLocked(filter.receiverList.uid, filter.packageName,
-                    -1)) {
+            final int allowed = mService.checkAllowBackgroundLocked(filter.receiverList.uid,
+                    filter.packageName, -1);
+            if (allowed == ActivityManager.APP_START_MODE_DISABLED) {
                 Slog.w(TAG, "Background execution not allowed: receiving "
                         + r.intent
                         + " to " + filter.receiverList.app
@@ -575,64 +576,70 @@
 
         if (!mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
                 r.callingPid, r.resolvedType, filter.receiverList.uid)) {
-            return;
+            skip = true;
         }
 
-        if (filter.receiverList.app == null || filter.receiverList.app.crashing) {
+        if (!skip && (filter.receiverList.app == null || filter.receiverList.app.crashing)) {
             Slog.w(TAG, "Skipping deliver [" + mQueueName + "] " + r
                     + " to " + filter.receiverList + ": process crashing");
             skip = true;
         }
 
-        if (!skip) {
-            // If permissions need a review before any of the app components can run, we drop
-            // the broadcast and if the calling app is in the foreground and the broadcast is
-            // explicit we launch the review UI passing it a pending intent to send the skipped
-            // broadcast.
-            if (Build.PERMISSIONS_REVIEW_REQUIRED) {
-                if (!requestStartTargetPermissionsReviewIfNeededLocked(r, filter.packageName,
-                        filter.owningUserId)) {
-                    return;
-                }
-            }
+        if (skip) {
+            r.delivery[index] = BroadcastRecord.DELIVERY_SKIPPED;
+            return;
+        }
 
-            // If this is not being sent as an ordered broadcast, then we
-            // don't want to touch the fields that keep track of the current
-            // state of ordered broadcasts.
-            if (ordered) {
-                r.receiver = filter.receiverList.receiver.asBinder();
-                r.curFilter = filter;
-                filter.receiverList.curBroadcast = r;
-                r.state = BroadcastRecord.CALL_IN_RECEIVE;
-                if (filter.receiverList.app != null) {
-                    // Bump hosting application to no longer be in background
-                    // scheduling class.  Note that we can't do that if there
-                    // isn't an app...  but we can only be in that case for
-                    // things that directly call the IActivityManager API, which
-                    // are already core system stuff so don't matter for this.
-                    r.curApp = filter.receiverList.app;
-                    filter.receiverList.app.curReceiver = r;
-                    mService.updateOomAdjLocked(r.curApp);
-                }
+        // If permissions need a review before any of the app components can run, we drop
+        // the broadcast and if the calling app is in the foreground and the broadcast is
+        // explicit we launch the review UI passing it a pending intent to send the skipped
+        // broadcast.
+        if (Build.PERMISSIONS_REVIEW_REQUIRED) {
+            if (!requestStartTargetPermissionsReviewIfNeededLocked(r, filter.packageName,
+                    filter.owningUserId)) {
+                r.delivery[index] = BroadcastRecord.DELIVERY_SKIPPED;
+                return;
             }
-            try {
-                if (DEBUG_BROADCAST_LIGHT) Slog.i(TAG_BROADCAST,
-                        "Delivering to " + filter + " : " + r);
-                performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
-                        new Intent(r.intent), r.resultCode, r.resultData,
-                        r.resultExtras, r.ordered, r.initialSticky, r.userId);
-                if (ordered) {
-                    r.state = BroadcastRecord.CALL_DONE_RECEIVE;
-                }
-            } catch (RemoteException e) {
-                Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
-                if (ordered) {
-                    r.receiver = null;
-                    r.curFilter = null;
-                    filter.receiverList.curBroadcast = null;
-                    if (filter.receiverList.app != null) {
-                        filter.receiverList.app.curReceiver = null;
-                    }
+        }
+
+        r.delivery[index] = BroadcastRecord.DELIVERY_DELIVERED;
+
+        // If this is not being sent as an ordered broadcast, then we
+        // don't want to touch the fields that keep track of the current
+        // state of ordered broadcasts.
+        if (ordered) {
+            r.receiver = filter.receiverList.receiver.asBinder();
+            r.curFilter = filter;
+            filter.receiverList.curBroadcast = r;
+            r.state = BroadcastRecord.CALL_IN_RECEIVE;
+            if (filter.receiverList.app != null) {
+                // Bump hosting application to no longer be in background
+                // scheduling class.  Note that we can't do that if there
+                // isn't an app...  but we can only be in that case for
+                // things that directly call the IActivityManager API, which
+                // are already core system stuff so don't matter for this.
+                r.curApp = filter.receiverList.app;
+                filter.receiverList.app.curReceiver = r;
+                mService.updateOomAdjLocked(r.curApp);
+            }
+        }
+        try {
+            if (DEBUG_BROADCAST_LIGHT) Slog.i(TAG_BROADCAST,
+                    "Delivering to " + filter + " : " + r);
+            performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
+                    new Intent(r.intent), r.resultCode, r.resultData,
+                    r.resultExtras, r.ordered, r.initialSticky, r.userId);
+            if (ordered) {
+                r.state = BroadcastRecord.CALL_DONE_RECEIVE;
+            }
+        } catch (RemoteException e) {
+            Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
+            if (ordered) {
+                r.receiver = null;
+                r.curFilter = null;
+                filter.receiverList.curBroadcast = null;
+                if (filter.receiverList.app != null) {
+                    filter.receiverList.app.curReceiver = null;
                 }
             }
         }
@@ -739,7 +746,7 @@
                     if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
                             "Delivering non-ordered on [" + mQueueName + "] to registered "
                             + target + ": " + r);
-                    deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
+                    deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
                 }
                 addBroadcastToHistoryLocked(r);
                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Done with parallel broadcast ["
@@ -896,7 +903,7 @@
                         "Delivering ordered ["
                         + mQueueName + "] to registered "
                         + filter + ": " + r);
-                deliverToRegisteredReceiverLocked(r, filter, r.ordered);
+                deliverToRegisteredReceiverLocked(r, filter, r.ordered, recIdx);
                 if (r.receiver == null || !r.ordered) {
                     // The receiver has already finished, so schedule to
                     // process the next one.
@@ -924,10 +931,17 @@
                     info.activityInfo.name);
 
             boolean skip = false;
+            if (brOptions != null &&
+                    (info.activityInfo.applicationInfo.targetSdkVersion
+                            < brOptions.getMinManifestReceiverApiLevel() ||
+                    info.activityInfo.applicationInfo.targetSdkVersion
+                            > brOptions.getMaxManifestReceiverApiLevel())) {
+                skip = true;
+            }
             int perm = mService.checkComponentPermission(info.activityInfo.permission,
                     r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
                     info.activityInfo.exported);
-            if (perm != PackageManager.PERMISSION_GRANTED) {
+            if (!skip && perm != PackageManager.PERMISSION_GRANTED) {
                 if (!info.activityInfo.exported) {
                     Slog.w(TAG, "Permission Denial: broadcasting "
                             + r.intent.toString()
@@ -944,7 +958,7 @@
                             + " due to receiver " + component.flattenToShortString());
                 }
                 skip = true;
-            } else if (info.activityInfo.permission != null) {
+            } else if (!skip && info.activityInfo.permission != null) {
                 final int opCode = AppOpsManager.permissionToOpCode(info.activityInfo.permission);
                 if (opCode != AppOpsManager.OP_NONE
                         && mService.mAppOpsService.noteOperation(opCode, r.callingUid,
@@ -1013,15 +1027,6 @@
                 skip = true;
             }
             if (!skip) {
-                if (!mService.checkAllowBackgroundLocked(info.activityInfo.applicationInfo.uid,
-                        info.activityInfo.packageName, -1)) {
-                    Slog.w(TAG, "Background execution not allowed: receiving "
-                            + r.intent + " to "
-                            + component.flattenToShortString());
-                    skip = true;
-                }
-            }
-            if (!skip) {
                 skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
                         r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid);
             }
@@ -1083,10 +1088,50 @@
                 }
             }
 
+            // This is safe to do even if we are skipping the broadcast, and we need
+            // this information now to evaluate whether it is going to be allowed to run.
+            final int receiverUid = info.activityInfo.applicationInfo.uid;
+            // If it's a singleton, it needs to be the same app or a special app
+            if (r.callingUid != Process.SYSTEM_UID && isSingleton
+                    && mService.isValidSingletonCall(r.callingUid, receiverUid)) {
+                info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0);
+            }
+            String targetProcess = info.activityInfo.processName;
+            ProcessRecord app = mService.getProcessRecordLocked(targetProcess,
+                    info.activityInfo.applicationInfo.uid, false);
+
+            if (!skip) {
+                final int allowed = mService.checkAllowBackgroundLocked(
+                        info.activityInfo.applicationInfo.uid, info.activityInfo.packageName, -1);
+                if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
+                    // We won't allow this receiver to be launched if the app has been
+                    // completely disabled from launches, or it is delayed and the broadcast
+                    // was not explicitly sent to it and this would result in a new process
+                    // for it being created.
+                    if (allowed == ActivityManager.APP_START_MODE_DISABLED) {
+                        Slog.w(TAG, "Background execution disabled: receiving "
+                                + r.intent + " to "
+                                + component.flattenToShortString());
+                        skip = true;
+                    }
+                    if (((r.intent.getFlags()&Intent.FLAG_RECEIVER_EXCLUDE_BACKGROUND) != 0)
+                            || (r.intent.getComponent() == null
+                                && r.intent.getPackage() == null && app == null
+                                && ((r.intent.getFlags()
+                                        & Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0))) {
+                        Slog.w(TAG, "Background execution not allowed: receiving "
+                                + r.intent + " to "
+                                + component.flattenToShortString());
+                        skip = true;
+                    }
+                }
+            }
+
             if (skip) {
                 if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
                         "Skipping delivery of ordered [" + mQueueName + "] "
                         + r + " for whatever reason");
+                r.delivery[recIdx] = BroadcastRecord.DELIVERY_SKIPPED;
                 r.receiver = null;
                 r.curFilter = null;
                 r.state = BroadcastRecord.IDLE;
@@ -1094,15 +1139,9 @@
                 return;
             }
 
+            r.delivery[recIdx] = BroadcastRecord.DELIVERY_DELIVERED;
             r.state = BroadcastRecord.APP_RECEIVE;
-            String targetProcess = info.activityInfo.processName;
             r.curComponent = component;
-            final int receiverUid = info.activityInfo.applicationInfo.uid;
-            // If it's a singleton, it needs to be the same app or a special app
-            if (r.callingUid != Process.SYSTEM_UID && isSingleton
-                    && mService.isValidSingletonCall(r.callingUid, receiverUid)) {
-                info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0);
-            }
             r.curReceiver = info.activityInfo;
             if (DEBUG_MU && r.callingUid > UserHandle.PER_USER_RANGE) {
                 Slog.v(TAG_MU, "Updated broadcast record activity info for secondary user, "
@@ -1126,8 +1165,6 @@
             }
 
             // Is this receiver's application already running?
-            ProcessRecord app = mService.getProcessRecordLocked(targetProcess,
-                    info.activityInfo.applicationInfo.uid, false);
             if (app != null && app.thread != null) {
                 try {
                     app.addPackage(info.activityInfo.packageName,
@@ -1272,6 +1309,7 @@
         String anrMessage = null;
 
         Object curReceiver = r.receivers.get(r.nextReceiver-1);
+        r.delivery[r.nextReceiver-1] = BroadcastRecord.DELIVERY_TIMEOUT;
         Slog.w(TAG, "Receiver during timeout: " + curReceiver);
         logBroadcastReceiverDiscardLocked(r);
         if (curReceiver instanceof BroadcastFilter) {
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index b42bcff..e99cbf9 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -57,6 +57,7 @@
     final int appOp;        // an app op that is associated with this broadcast
     final BroadcastOptions options; // BroadcastOptions supplied by caller
     final List receivers;   // contains BroadcastFilter and ResolveInfo
+    final int[] delivery;   // delivery state of each receiver
     IIntentReceiver resultTo; // who receives final result if non-null
     long enqueueClockTime;  // the clock time the broadcast was enqueued
     long dispatchTime;      // when dispatch started on this set of receivers
@@ -79,6 +80,11 @@
     static final int CALL_DONE_RECEIVE = 3;
     static final int WAITING_SERVICES = 4;
 
+    static final int DELIVERY_PENDING = 0;
+    static final int DELIVERY_DELIVERED = 1;
+    static final int DELIVERY_SKIPPED = 2;
+    static final int DELIVERY_TIMEOUT = 3;
+
     // The following are set when we are calling a receiver (one that
     // was found in our list of registered receivers).
     BroadcastFilter curFilter;
@@ -183,12 +189,24 @@
         PrintWriterPrinter printer = new PrintWriterPrinter(pw);
         for (int i = 0; i < N; i++) {
             Object o = receivers.get(i);
-            pw.print(prefix); pw.print("Receiver #"); pw.print(i);
-                    pw.print(": "); pw.println(o);
-            if (o instanceof BroadcastFilter)
-                ((BroadcastFilter)o).dumpBrief(pw, p2);
-            else if (o instanceof ResolveInfo)
-                ((ResolveInfo)o).dump(printer, p2);
+            pw.print(prefix);
+            switch (delivery[i]) {
+                case DELIVERY_PENDING:   pw.print("Pending"); break;
+                case DELIVERY_DELIVERED: pw.print("Deliver"); break;
+                case DELIVERY_SKIPPED:   pw.print("Skipped"); break;
+                case DELIVERY_TIMEOUT:   pw.print("Timeout"); break;
+                default:                 pw.print("???????"); break;
+            }
+            pw.print(" #"); pw.print(i); pw.print(": ");
+            if (o instanceof BroadcastFilter) {
+                pw.println(o);
+                ((BroadcastFilter) o).dumpBrief(pw, p2);
+            } else if (o instanceof ResolveInfo) {
+                pw.println("(manifest)");
+                ((ResolveInfo) o).dump(printer, p2, 0);
+            } else {
+                pw.println(o);
+            }
         }
     }
 
@@ -211,6 +229,7 @@
         appOp = _appOp;
         options = _options;
         receivers = _receivers;
+        delivery = new int[_receivers != null ? _receivers.size() : 0];
         resultTo = _resultTo;
         resultCode = _resultCode;
         resultData = _resultData;
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index f6f82da..62e78a4 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -253,7 +253,8 @@
 
                 final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
                 bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
-                bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
+                bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
+                        | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
                 mService.broadcastIntentLocked(null, null, bootIntent, null, null, 0, null, null,
                         new String[] { android.Manifest.permission.RECEIVE_BOOT_COMPLETED },
                         AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 4f2f486..40d01e7 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -197,7 +197,7 @@
     private static final int MSG_SET_DEVICE_VOLUME = 0;
     private static final int MSG_PERSIST_VOLUME = 1;
     private static final int MSG_PERSIST_RINGER_MODE = 3;
-    private static final int MSG_MEDIA_SERVER_DIED = 4;
+    private static final int MSG_AUDIO_SERVER_DIED = 4;
     private static final int MSG_PLAY_SOUND_EFFECT = 5;
     private static final int MSG_BTA2DP_DOCK_TIMEOUT = 6;
     private static final int MSG_LOAD_SOUND_EFFECTS = 7;
@@ -358,7 +358,7 @@
         public void onError(int error) {
             switch (error) {
             case AudioSystem.AUDIO_STATUS_SERVER_DIED:
-                sendMsg(mAudioHandler, MSG_MEDIA_SERVER_DIED,
+                sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED,
                         SENDMSG_NOOP, 0, 0, null, 0);
                 break;
             default:
@@ -772,15 +772,15 @@
                 INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
     }
 
-    public void onMediaServerDied() {
+    public void onAudioServerDied() {
         if (!mSystemReady ||
                 (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) {
-            Log.e(TAG, "Media server died.");
-            sendMsg(mAudioHandler, MSG_MEDIA_SERVER_DIED, SENDMSG_NOOP, 0, 0,
+            Log.e(TAG, "Audioserver died.");
+            sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0,
                     null, 500);
             return;
         }
-        Log.e(TAG, "Media server started.");
+        Log.e(TAG, "Audioserver started.");
 
         // indicate to audio HAL that we start the reconfiguration phase after a media
         // server crash
@@ -4406,8 +4406,8 @@
                     persistRingerMode(getRingerModeInternal());
                     break;
 
-                case MSG_MEDIA_SERVER_DIED:
-                    onMediaServerDied();
+                case MSG_AUDIO_SERVER_DIED:
+                    onAudioServerDied();
                     break;
 
                 case MSG_UNLOAD_SOUND_EFFECTS:
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index 5108564..3a10dbe 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -62,6 +62,7 @@
 import com.android.internal.util.Protocol;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
+import com.android.internal.util.WakeupMessage;
 import com.android.server.connectivity.NetworkAgentInfo;
 
 import java.io.IOException;
@@ -565,19 +566,14 @@
     private class LingeringState extends State {
         private static final String ACTION_LINGER_EXPIRED = "android.net.netmon.lingerExpired";
 
-        private CustomIntentReceiver mBroadcastReceiver;
-        private PendingIntent mIntent;
+        private WakeupMessage mWakeupMessage;
 
         @Override
         public void enter() {
-            mLingerToken = new Random().nextInt();
-            mBroadcastReceiver = new CustomIntentReceiver(ACTION_LINGER_EXPIRED, mLingerToken,
-                    CMD_LINGER_EXPIRED);
-            mIntent = mBroadcastReceiver.getPendingIntent();
+            final String cmdName = ACTION_LINGER_EXPIRED + "." + mNetworkAgentInfo.network.netId;
+            mWakeupMessage = new WakeupMessage(mContext, getHandler(), cmdName, CMD_LINGER_EXPIRED);
             long wakeupTime = SystemClock.elapsedRealtime() + mLingerDelayMs;
-            mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, wakeupTime,
-                    // Give a specific window so we aren't subject to unknown inexactitude.
-                    mLingerDelayMs / 6, mIntent);
+            mWakeupMessage.schedule(wakeupTime);
         }
 
         @Override
@@ -592,8 +588,6 @@
                     }
                     return NOT_HANDLED;
                 case CMD_LINGER_EXPIRED:
-                    if (message.arg1 != mLingerToken)
-                        return HANDLED;
                     mConnectivityServiceHandler.sendMessage(
                             obtainMessage(EVENT_NETWORK_LINGER_COMPLETE, mNetworkAgentInfo));
                     return HANDLED;
@@ -624,8 +618,7 @@
 
         @Override
         public void exit() {
-            mAlarmManager.cancel(mIntent);
-            mContext.unregisterReceiver(mBroadcastReceiver);
+            mWakeupMessage.cancel();
         }
     }
 
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index a066835..78618ce 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -345,25 +345,9 @@
     }
 
     public void updateRunningAccounts() {
-        mRunningAccounts = AccountManagerService.getSingleton().getRunningAccounts();
-
-        if (mBootCompleted) {
-            doDatabaseCleanup();
-        }
-
-        AccountAndUser[] accounts = mRunningAccounts;
-        for (ActiveSyncContext currentSyncContext : mActiveSyncContexts) {
-            if (!containsAccountAndUser(accounts,
-                    currentSyncContext.mSyncOperation.target.account,
-                    currentSyncContext.mSyncOperation.target.userId)) {
-                Log.d(TAG, "canceling sync since the account is no longer running");
-                sendSyncFinishedOrCanceledMessage(currentSyncContext,
-                        null /* no result since this is a cancel */);
-            }
-        }
-        // we must do this since we don't bother scheduling alarms when
-        // the accounts are not set yet
-        sendCheckAlarmsMessage();
+        if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "sending MESSAGE_ACCOUNTS_UPDATED");
+        // Update accounts in handler thread.
+        mSyncHandler.sendEmptyMessage(SyncHandler.MESSAGE_ACCOUNTS_UPDATED);
     }
 
     private void doDatabaseCleanup() {
@@ -2179,6 +2163,7 @@
          * obj: {@link com.android.server.content.SyncManager.ActiveSyncContext}
          */
         private static final int MESSAGE_MONITOR_SYNC = 8;
+        private static final int MESSAGE_ACCOUNTS_UPDATED = 9;
 
         public final SyncNotificationInfo mSyncNotificationInfo = new SyncNotificationInfo();
         private Long mAlarmScheduleTime = null;
@@ -2296,6 +2281,13 @@
                 // to also take into account the periodic syncs.
                 earliestFuturePollTime = scheduleReadyPeriodicSyncs();
                 switch (msg.what) {
+                    case SyncHandler.MESSAGE_ACCOUNTS_UPDATED:
+                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                            Log.v(TAG, "handleSyncHandlerMessage: MESSAGE_ACCOUNTS_UPDATED");
+                        }
+                        updateRunningAccountsH();
+                        break;
+
                     case SyncHandler.MESSAGE_CANCEL:
                         SyncStorageEngine.EndPoint endpoint = (SyncStorageEngine.EndPoint) msg.obj;
                         Bundle extras = msg.peekData();
@@ -2872,7 +2864,28 @@
                     mLocalDeviceIdleController.setSyncActive(active);
                 }
             }
+        }
 
+        private void updateRunningAccountsH() {
+            mRunningAccounts = AccountManagerService.getSingleton().getRunningAccounts();
+
+            if (mBootCompleted) {
+                doDatabaseCleanup();
+            }
+
+            AccountAndUser[] accounts = mRunningAccounts;
+            for (ActiveSyncContext currentSyncContext : mActiveSyncContexts) {
+                if (!containsAccountAndUser(accounts,
+                        currentSyncContext.mSyncOperation.target.account,
+                        currentSyncContext.mSyncOperation.target.userId)) {
+                    Log.d(TAG, "canceling sync since the account is no longer running");
+                    sendSyncFinishedOrCanceledMessage(currentSyncContext,
+                            null /* no result since this is a cancel */);
+                }
+            }
+            // we must do this since we don't bother scheduling alarms when
+            // the accounts are not set yet
+            sendCheckAlarmsMessage();
         }
 
         private boolean isSyncNotUsingNetworkH(ActiveSyncContext activeSyncContext) {
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 103ed0a..e0a9975 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -19,12 +19,11 @@
 import android.Manifest;
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningAppProcessInfo;
-import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityManagerNative;
 import android.app.AlarmManager;
 import android.app.AppOpsManager;
-import android.app.IUserSwitchObserver;
 import android.app.PendingIntent;
+import android.app.SynchronousUserSwitchObserver;
 import android.content.ComponentName;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -38,7 +37,6 @@
 import android.os.Environment;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.IRemoteCallback;
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.SELinux;
@@ -1134,17 +1132,11 @@
     private void listenForUserSwitches() {
         try {
             ActivityManagerNative.getDefault().registerUserSwitchObserver(
-                new IUserSwitchObserver.Stub() {
+                new SynchronousUserSwitchObserver() {
                     @Override
-                    public void onUserSwitching(int newUserId, IRemoteCallback reply) {
+                    public void onUserSwitching(int newUserId) throws RemoteException {
                         mHandler.obtainMessage(MSG_USER_SWITCHING, newUserId, 0 /* unused */)
                                 .sendToTarget();
-                        if (reply != null) {
-                            try {
-                                reply.sendResult(null);
-                            } catch (RemoteException e) {
-                            }
-                        }
                     }
                     @Override
                     public void onUserSwitchComplete(int newUserId) throws RemoteException {
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 4d7df9c..309bec8 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -88,6 +88,7 @@
     static final int MSG_JOB_EXPIRED = 0;
     static final int MSG_CHECK_JOB = 1;
     static final int MSG_STOP_JOB = 2;
+    static final int MSG_CHECK_JOB_GREEDY = 3;
 
     // Policy constants
     /**
@@ -362,7 +363,8 @@
     }
 
     void reportActive() {
-        boolean active = false;
+        // active is true if pending queue contains jobs OR some job is running.
+        boolean active = mPendingJobs.size() > 0;
         if (mPendingJobs.size() <= 0) {
             for (int i=0; i<mActiveServices.size(); i++) {
                 JobServiceContext jsc = mActiveServices.get(i);
@@ -372,9 +374,10 @@
                 }
             }
         }
-        if (mLocalDeviceIdleController != null) {
-            if (mReportedActive != active) {
-                mReportedActive = active;
+
+        if (mReportedActive != active) {
+            mReportedActive = active;
+            if (mLocalDeviceIdleController != null) {
                 mLocalDeviceIdleController.setJobsActive(active);
             }
         }
@@ -628,7 +631,8 @@
             JobStatus rescheduledPeriodic = getRescheduleJobForPeriodic(jobStatus);
             startTrackingJob(rescheduledPeriodic);
         }
-        mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
+        reportActive();
+        mHandler.obtainMessage(MSG_CHECK_JOB_GREEDY).sendToTarget();
     }
 
     // StateChangedListener implementations.
@@ -676,8 +680,18 @@
                     break;
                 case MSG_CHECK_JOB:
                     synchronized (mJobs) {
-                        // Check the list of jobs and run some of them if we feel inclined.
-                        maybeQueueReadyJobsForExecutionLockedH();
+                        if (mReportedActive) {
+                            // if jobs are currently being run, queue all ready jobs for execution.
+                            queueReadyJobsForExecutionLockedH();
+                        } else {
+                            // Check the list of jobs and run some of them if we feel inclined.
+                            maybeQueueReadyJobsForExecutionLockedH();
+                        }
+                    }
+                    break;
+                case MSG_CHECK_JOB_GREEDY:
+                    synchronized (mJobs) {
+                        queueReadyJobsForExecutionLockedH();
                     }
                     break;
                 case MSG_STOP_JOB:
@@ -709,7 +723,6 @@
                     stopJobOnServiceContextLocked(job);
                 }
             }
-            reportActive();
             if (DEBUG) {
                 final int queuedJobs = mPendingJobs.size();
                 if (queuedJobs == 0) {
@@ -786,7 +799,6 @@
                     Slog.d(TAG, "maybeQueueReadyJobsForExecutionLockedH: Not running anything.");
                 }
             }
-            reportActive();
             if (DEBUG) {
                 Slog.d(TAG, "idle=" + idleCount + " connectivity=" +
                 connectivityCount + " charging=" + chargingCount + " tot=" +
diff --git a/services/core/java/com/android/server/job/controllers/TimeController.java b/services/core/java/com/android/server/job/controllers/TimeController.java
index b3d7287..33b09e3 100644
--- a/services/core/java/com/android/server/job/controllers/TimeController.java
+++ b/services/core/java/com/android/server/job/controllers/TimeController.java
@@ -17,11 +17,8 @@
 package com.android.server.job.controllers;
 
 import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
+import android.app.AlarmManager.OnAlarmListener;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.os.SystemClock;
 import android.util.Slog;
 
@@ -40,15 +37,11 @@
  */
 public class TimeController extends StateController {
     private static final String TAG = "JobScheduler.Time";
-    private static final String ACTION_JOB_EXPIRED =
-            "android.content.jobscheduler.JOB_DEADLINE_EXPIRED";
-    private static final String ACTION_JOB_DELAY_EXPIRED =
-            "android.content.jobscheduler.JOB_DELAY_EXPIRED";
 
-    /** Set an alarm for the next job expiry. */
-    private final PendingIntent mDeadlineExpiredAlarmIntent;
-    /** Set an alarm for the next job delay expiry. This*/
-    private final PendingIntent mNextDelayExpiredAlarmIntent;
+    /** Deadline alarm tag for logging purposes */
+    private final String DEADLINE_TAG = "deadline";
+    /** Delay alarm tag for logging purposes */
+    private final String DELAY_TAG = "delay";
 
     private long mNextJobExpiredElapsedMillis;
     private long mNextDelayExpiredElapsedMillis;
@@ -68,19 +61,9 @@
 
     private TimeController(StateChangedListener stateChangedListener, Context context) {
         super(stateChangedListener, context);
-        mDeadlineExpiredAlarmIntent =
-                PendingIntent.getBroadcast(mContext, 0 /* ignored */,
-                        new Intent(ACTION_JOB_EXPIRED), 0);
-        mNextDelayExpiredAlarmIntent =
-                PendingIntent.getBroadcast(mContext, 0 /* ignored */,
-                        new Intent(ACTION_JOB_DELAY_EXPIRED), 0);
+
         mNextJobExpiredElapsedMillis = Long.MAX_VALUE;
         mNextDelayExpiredElapsedMillis = Long.MAX_VALUE;
-
-        // Register BR for these intents.
-        IntentFilter intentFilter = new IntentFilter(ACTION_JOB_EXPIRED);
-        intentFilter.addAction(ACTION_JOB_DELAY_EXPIRED);
-        mContext.registerReceiver(mAlarmExpiredReceiver, intentFilter);
     }
 
     /**
@@ -224,7 +207,7 @@
     private void setDelayExpiredAlarm(long alarmTimeElapsedMillis) {
         alarmTimeElapsedMillis = maybeAdjustAlarmTime(alarmTimeElapsedMillis);
         mNextDelayExpiredElapsedMillis = alarmTimeElapsedMillis;
-        updateAlarmWithPendingIntent(mNextDelayExpiredAlarmIntent, mNextDelayExpiredElapsedMillis);
+        updateAlarmWithListener(DELAY_TAG, mNextDelayExpiredListener, mNextDelayExpiredElapsedMillis);
     }
 
     /**
@@ -235,7 +218,7 @@
     private void setDeadlineExpiredAlarm(long alarmTimeElapsedMillis) {
         alarmTimeElapsedMillis = maybeAdjustAlarmTime(alarmTimeElapsedMillis);
         mNextJobExpiredElapsedMillis = alarmTimeElapsedMillis;
-        updateAlarmWithPendingIntent(mDeadlineExpiredAlarmIntent, mNextJobExpiredElapsedMillis);
+        updateAlarmWithListener(DEADLINE_TAG, mDeadlineExpiredListener, mNextJobExpiredElapsedMillis);
     }
 
     private long maybeAdjustAlarmTime(long proposedAlarmTimeElapsedMillis) {
@@ -246,31 +229,39 @@
         return proposedAlarmTimeElapsedMillis;
     }
 
-    private void updateAlarmWithPendingIntent(PendingIntent pi, long alarmTimeElapsed) {
+    private void updateAlarmWithListener(String tag, OnAlarmListener listener,
+            long alarmTimeElapsed) {
         ensureAlarmService();
         if (alarmTimeElapsed == Long.MAX_VALUE) {
-            mAlarmService.cancel(pi);
+            mAlarmService.cancel(listener);
         } else {
             if (DEBUG) {
-                Slog.d(TAG, "Setting " + pi.getIntent().getAction() + " for: " + alarmTimeElapsed);
+                Slog.d(TAG, "Setting " + tag + " for: " + alarmTimeElapsed);
             }
-            mAlarmService.set(AlarmManager.ELAPSED_REALTIME, alarmTimeElapsed, pi);
+            mAlarmService.set(AlarmManager.ELAPSED_REALTIME, alarmTimeElapsed,
+                    tag, listener, null);
         }
     }
 
-    private final BroadcastReceiver mAlarmExpiredReceiver = new BroadcastReceiver() {
+    // Job/delay expiration alarm handling
+
+    private final OnAlarmListener mDeadlineExpiredListener = new OnAlarmListener() {
         @Override
-        public void onReceive(Context context, Intent intent) {
+        public void onAlarm() {
             if (DEBUG) {
-                Slog.d(TAG, "Just received alarm: " + intent.getAction());
+                Slog.d(TAG, "Deadline-expired alarm fired");
             }
-            // A job has just expired, so we run through the list of jobs that we have and
-            // notify our StateChangedListener.
-            if (ACTION_JOB_EXPIRED.equals(intent.getAction())) {
-                checkExpiredDeadlinesAndResetAlarm();
-            } else if (ACTION_JOB_DELAY_EXPIRED.equals(intent.getAction())) {
-                checkExpiredDelaysAndResetAlarm();
+            checkExpiredDeadlinesAndResetAlarm();
+        }
+    };
+
+    private final OnAlarmListener mNextDelayExpiredListener = new OnAlarmListener() {
+        @Override
+        public void onAlarm() {
+            if (DEBUG) {
+                Slog.d(TAG, "Delay-expired alarm fired");
             }
+            checkExpiredDelaysAndResetAlarm();
         }
     };
 
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 9f8148c..dd5baec 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -160,8 +160,8 @@
 public class NotificationManagerService extends SystemService {
     static final String TAG = "NotificationService";
     static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
-    public static final boolean ENABLE_CHILD_NOTIFICATIONS = Build.IS_DEBUGGABLE
-            && SystemProperties.getBoolean("debug.child_notifs", false);
+    public static final boolean ENABLE_CHILD_NOTIFICATIONS
+            = SystemProperties.getBoolean("debug.child_notifs", true);
 
     static final int MAX_PACKAGE_NOTIFICATIONS = 50;
 
diff --git a/services/core/java/com/android/server/os/SchedulingPolicyService.java b/services/core/java/com/android/server/os/SchedulingPolicyService.java
index c0123bf..80faf473 100644
--- a/services/core/java/com/android/server/os/SchedulingPolicyService.java
+++ b/services/core/java/com/android/server/os/SchedulingPolicyService.java
@@ -40,12 +40,13 @@
     public int requestPriority(int pid, int tid, int prio) {
         //Log.i(TAG, "requestPriority(pid=" + pid + ", tid=" + tid + ", prio=" + prio + ")");
 
-        // Verify that caller is mediaserver, priority is in range, and that the
-        // callback thread specified by app belongs to the app that called mediaserver.
-        // Once we've verified that the caller is mediaserver, we can trust the pid but
+        // Verify that the caller uid is permitted, priority is in range,
+        // and that the callback thread specified by app belongs to the app that
+        // called mediaserver or audioserver.
+        // Once we've verified that the caller uid is permitted, we can trust the pid but
         // we can't trust the tid.  No need to explicitly check for pid == 0 || tid == 0,
         // since if not the case then the getThreadGroupLeader() test will also fail.
-        if (Binder.getCallingUid() != Process.MEDIA_UID || prio < PRIORITY_MIN ||
+        if (!isPermittedCallingUid() || prio < PRIORITY_MIN ||
                 prio > PRIORITY_MAX || Process.getThreadGroupLeader(tid) != pid) {
             return PackageManager.PERMISSION_DENIED;
         }
@@ -61,4 +62,14 @@
         return PackageManager.PERMISSION_GRANTED;
     }
 
+    private boolean isPermittedCallingUid() {
+        final int callingUid = Binder.getCallingUid();
+        switch (callingUid) {
+        case Process.AUDIOSERVER_UID: // fastcapture, fastmixer
+        case Process.MEDIA_UID: // camera
+            return true;
+        default:
+            return false;
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/pm/EphemeralApplicationRegistry.java b/services/core/java/com/android/server/pm/EphemeralApplicationRegistry.java
new file mode 100644
index 0000000..8786350
--- /dev/null
+++ b/services/core/java/com/android/server/pm/EphemeralApplicationRegistry.java
@@ -0,0 +1,698 @@
+/*
+ * 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.Context;
+import android.content.pm.EphemeralApplicationInfo;
+import android.content.pm.PackageParser;
+import android.content.pm.PackageUserState;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Binder;
+import android.os.Environment;
+import android.provider.Settings;
+import android.util.AtomicFile;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.Xml;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.XmlUtils;
+import libcore.io.IoUtils;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This class is a part of the package manager service that is responsible
+ * for managing data associated with ephemeral apps such as cached uninstalled
+ * ephemeral apps and ephemeral apps' cookies.
+ */
+class EphemeralApplicationRegistry {
+    private static final boolean DEBUG = false;
+
+    private static final String LOG_TAG = "EphemeralAppRegistry";
+
+    private static final long DEFAULT_UNINSTALLED_EPHEMERAL_APP_CACHE_DURATION_MILLIS =
+            DEBUG ? 60 * 1000L /* one min */ : 30 * 24 * 60 * 60 * 1000L; /* one month */
+
+    private final static char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
+
+    private static final String EPHEMERAL_APPS_FOLDER = "ephemeral";
+    private static final String EPHEMERAL_APP_ICON_FILE = "icon.png";
+    private static final String EPHEMERAL_APP_COOKIE_FILE_PREFIX = "cookie_";
+    private static final String EPHEMERAL_APP_COOKIE_FILE_SIFFIX = ".dat";
+    private static final String EPHEMERAL_APP_METADATA_FILE = "metadata.xml";
+
+    private static final String TAG_PACKAGE = "package";
+    private static final String TAG_PERMS = "perms";
+    private static final String TAG_PERM = "perm";
+
+    private static final String ATTR_LABEL = "label";
+    private static final String ATTR_NAME = "name";
+    private static final String ATTR_GRANTED = "granted";
+
+    private final PackageManagerService mService;
+
+    @GuardedBy("mService.mPackages")
+    private SparseArray<List<UninstalledEphemeralAppState>> mUninstalledEphemeralApps;
+
+    public EphemeralApplicationRegistry(PackageManagerService service) {
+        mService = service;
+    }
+
+    public byte[] getEphemeralApplicationCookieLPw(String packageName, int userId) {
+        pruneUninstalledEphemeralAppsLPw(userId);
+
+        File cookieFile = peekEphemeralCookieFile(packageName, userId);
+        if (cookieFile != null && cookieFile.exists()) {
+            try {
+                return IoUtils.readFileAsByteArray(cookieFile.toString());
+            } catch (IOException e) {
+                Slog.w(LOG_TAG, "Error reading cookie file: " + cookieFile);
+            }
+        }
+        return null;
+    }
+
+    public boolean setEphemeralApplicationCookieLPw(String packageName,
+            byte[] cookie, int userId) {
+        pruneUninstalledEphemeralAppsLPw(userId);
+
+        PackageParser.Package pkg = mService.mPackages.get(packageName);
+        if (pkg == null) {
+            return false;
+        }
+
+        if (!isValidCookie(mService.mContext, cookie)) {
+            return false;
+        }
+
+        File appDir = getEphemeralApplicationDir(pkg.packageName, userId);
+        if (!appDir.exists() && !appDir.mkdirs()) {
+            return false;
+        }
+
+        File cookieFile = computeEphemeralCookieFile(pkg, userId);
+        if (cookieFile.exists() && !cookieFile.delete()) {
+            return false;
+        }
+
+        try (FileOutputStream fos = new FileOutputStream(cookieFile)) {
+            fos.write(cookie, 0, cookie.length);
+        } catch (IOException e) {
+            Slog.w(LOG_TAG, "Error writing cookie file: " + cookieFile);
+            return false;
+        }
+        return true;
+    }
+
+    public Bitmap getEphemeralApplicationIconLPw(String packageName, int userId) {
+        pruneUninstalledEphemeralAppsLPw(userId);
+
+        File iconFile = new File(getEphemeralApplicationDir(packageName, userId),
+                EPHEMERAL_APP_ICON_FILE);
+        if (iconFile.exists()) {
+            return BitmapFactory.decodeFile(iconFile.toString());
+        }
+        return null;
+    }
+
+    public List<EphemeralApplicationInfo> getEphemeralApplicationsLPw(int userId) {
+        pruneUninstalledEphemeralAppsLPw(userId);
+
+        List<EphemeralApplicationInfo> result = getInstalledEphemeralApplicationsLPr(userId);
+        result.addAll(getUninstalledEphemeralApplicationsLPr(userId));
+        return result;
+    }
+
+    public void onPackageInstalledLPw(PackageParser.Package pkg) {
+        PackageSetting ps = (PackageSetting) pkg.mExtras;
+        if (ps == null) {
+            return;
+        }
+        for (int userId : UserManagerService.getInstance().getUserIds()) {
+            pruneUninstalledEphemeralAppsLPw(userId);
+
+            // Ignore not installed apps
+            if (mService.mPackages.get(pkg.packageName) == null || !ps.getInstalled(userId)) {
+                continue;
+            }
+
+            // Propagate permissions before removing any state
+            propagateEphemeralAppPermissionsIfNeeded(pkg, userId);
+
+            // Remove the in-memory state
+            if (mUninstalledEphemeralApps != null) {
+                List<UninstalledEphemeralAppState> uninstalledAppStates =
+                        mUninstalledEphemeralApps.get(userId);
+                if (uninstalledAppStates != null) {
+                    final int appCount = uninstalledAppStates.size();
+                    for (int i = 0; i < appCount; i++) {
+                        UninstalledEphemeralAppState uninstalledAppState =
+                                uninstalledAppStates.get(i);
+                        if (uninstalledAppState.mEphemeralApplicationInfo
+                                .getPackageName().equals(pkg.packageName)) {
+                            uninstalledAppStates.remove(i);
+                            break;
+                        }
+                    }
+                }
+            }
+
+            // Remove the on-disk state except the cookie
+            File ephemeralAppDir = getEphemeralApplicationDir(pkg.packageName, userId);
+            new File(ephemeralAppDir, EPHEMERAL_APP_METADATA_FILE).delete();
+            new File(ephemeralAppDir, EPHEMERAL_APP_ICON_FILE).delete();
+
+            // If app signature changed - wipe the cookie
+            File currentCookieFile = peekEphemeralCookieFile(pkg.packageName, userId);
+            if (currentCookieFile == null) {
+                continue;
+            }
+            File expectedCookeFile = computeEphemeralCookieFile(pkg, userId);
+            if (!currentCookieFile.equals(expectedCookeFile)) {
+                Slog.i(LOG_TAG, "Signature for package " + pkg.packageName
+                        + " changed - dropping cookie");
+                currentCookieFile.delete();
+            }
+        }
+    }
+
+    public void onPackageUninstalledLPw(PackageParser.Package pkg) {
+        PackageSetting ps = (PackageSetting) pkg.mExtras;
+        if (ps == null) {
+            return;
+        }
+        for (int userId : UserManagerService.getInstance().getUserIds()) {
+            pruneUninstalledEphemeralAppsLPw(userId);
+
+            if (mService.mPackages.get(pkg.packageName) != null && ps.getInstalled(userId)) {
+                continue;
+            }
+
+            if (pkg.applicationInfo.isEphemeralApp()) {
+                // Add a record for an uninstalled ephemeral app
+                addUninstalledEphemeralAppLPw(pkg, userId);
+            } else {
+                // Deleting an app prunes all ephemeral state such as cookie
+                deleteDir(getEphemeralApplicationDir(pkg.packageName, userId));
+            }
+        }
+    }
+
+    public void onUserRemovedLPw(int userId) {
+        if (mUninstalledEphemeralApps != null) {
+            mUninstalledEphemeralApps.remove(userId);
+        }
+        deleteDir(getEphemeralApplicationsDir(userId));
+    }
+
+    private void addUninstalledEphemeralAppLPw(PackageParser.Package pkg, int userId) {
+        EphemeralApplicationInfo uninstalledApp = createEphemeralAppInfoForPackage(pkg, userId);
+        if (uninstalledApp == null) {
+            return;
+        }
+        if (mUninstalledEphemeralApps == null) {
+            mUninstalledEphemeralApps = new SparseArray<>();
+        }
+        List<UninstalledEphemeralAppState> uninstalledAppStates =
+                mUninstalledEphemeralApps.get(userId);
+        if (uninstalledAppStates == null) {
+            uninstalledAppStates = new ArrayList<>();
+            mUninstalledEphemeralApps.put(userId, uninstalledAppStates);
+        }
+        UninstalledEphemeralAppState uninstalledAppState = new UninstalledEphemeralAppState(
+                uninstalledApp, System.currentTimeMillis());
+        uninstalledAppStates.add(uninstalledAppState);
+
+        writeUninstalledEphemeralAppMetadata(uninstalledApp, userId);
+        writeEphemeralApplicationIconLPw(pkg, userId);
+    }
+
+    private void writeEphemeralApplicationIconLPw(PackageParser.Package pkg, int userId) {
+        File appDir = getEphemeralApplicationDir(pkg.packageName, userId);
+        if (!appDir.exists()) {
+            return;
+        }
+
+        Drawable icon = pkg.applicationInfo.loadIcon(mService.mContext.getPackageManager());
+
+        final Bitmap bitmap;
+        if (icon instanceof BitmapDrawable) {
+            bitmap = ((BitmapDrawable) icon).getBitmap();
+        } else  {
+            bitmap = Bitmap.createBitmap(icon.getIntrinsicWidth(),
+                    icon.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
+            Canvas canvas = new Canvas(bitmap);
+            icon.draw(canvas);
+        }
+
+        File iconFile = new File(getEphemeralApplicationDir(pkg.packageName, userId),
+                EPHEMERAL_APP_ICON_FILE);
+
+        try (FileOutputStream out = new FileOutputStream(iconFile)) {
+            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
+        } catch (Exception e) {
+            Slog.e(LOG_TAG, "Error writing ephemeral app icon", e);
+        }
+    }
+
+    private void pruneUninstalledEphemeralAppsLPw(int userId) {
+        final long maxCacheDurationMillis = Settings.Global.getLong(
+                mService.mContext.getContentResolver(),
+                Settings.Global.UNINSTALLED_EPHEMERAL_APP_CACHE_DURATION_MILLIS,
+                DEFAULT_UNINSTALLED_EPHEMERAL_APP_CACHE_DURATION_MILLIS);
+
+        // Prune in-memory state
+        if (mUninstalledEphemeralApps != null) {
+            List<UninstalledEphemeralAppState> uninstalledAppStates =
+                    mUninstalledEphemeralApps.get(userId);
+            if (uninstalledAppStates != null) {
+                final int appCount = uninstalledAppStates.size();
+                for (int j = appCount - 1; j >= 0; j--) {
+                    UninstalledEphemeralAppState uninstalledAppState = uninstalledAppStates.get(j);
+                    final long elapsedCachingMillis = System.currentTimeMillis()
+                            - uninstalledAppState.mTimestamp;
+                    if (elapsedCachingMillis > maxCacheDurationMillis) {
+                        uninstalledAppStates.remove(j);
+                    }
+                }
+                if (uninstalledAppStates.isEmpty()) {
+                    mUninstalledEphemeralApps.remove(userId);
+                }
+            }
+        }
+
+        // Prune on-disk state
+        File ephemeralAppsDir = getEphemeralApplicationsDir(userId);
+        if (!ephemeralAppsDir.exists()) {
+            return;
+        }
+        File[] files = ephemeralAppsDir.listFiles();
+        if (files == null) {
+            return;
+        }
+        for (File ephemeralDir : files) {
+            if (!ephemeralDir.isDirectory()) {
+                continue;
+            }
+
+            File metadataFile = new File(ephemeralDir, EPHEMERAL_APP_METADATA_FILE);
+            if (!metadataFile.exists()) {
+                continue;
+            }
+
+            final long elapsedCachingMillis = System.currentTimeMillis()
+                    - metadataFile.lastModified();
+            if (elapsedCachingMillis > maxCacheDurationMillis) {
+                deleteDir(ephemeralDir);
+            }
+        }
+    }
+
+    private List<EphemeralApplicationInfo> getInstalledEphemeralApplicationsLPr(int userId) {
+        List<EphemeralApplicationInfo> result = null;
+
+        final int packageCount = mService.mPackages.size();
+        for (int i = 0; i < packageCount; i++) {
+            PackageParser.Package pkg = mService.mPackages.valueAt(i);
+            if (!pkg.applicationInfo.isEphemeralApp()) {
+                continue;
+            }
+            EphemeralApplicationInfo info = createEphemeralAppInfoForPackage(pkg, userId);
+            if (info == null) {
+                continue;
+            }
+            if (result == null) {
+                result = new ArrayList<>();
+            }
+            result.add(info);
+        }
+
+        return result;
+    }
+
+    private EphemeralApplicationInfo createEphemeralAppInfoForPackage(
+            PackageParser.Package pkg, int userId) {
+        PackageSetting ps = (PackageSetting) pkg.mExtras;
+        if (ps == null) {
+            return null;
+        }
+        PackageUserState userState = ps.readUserState(userId);
+        if (userState == null || !userState.installed || userState.hidden) {
+            return null;
+        }
+
+        String[] requestedPermissions = new String[pkg.requestedPermissions.size()];
+        pkg.requestedPermissions.toArray(requestedPermissions);
+
+        Set<String> permissions = ps.getPermissionsState().getPermissions(userId);
+        String[] grantedPermissions = new String[permissions.size()];
+        permissions.toArray(grantedPermissions);
+
+        return new EphemeralApplicationInfo(pkg.applicationInfo,
+                requestedPermissions, grantedPermissions);
+    }
+
+    private List<EphemeralApplicationInfo> getUninstalledEphemeralApplicationsLPr(int userId) {
+        List<UninstalledEphemeralAppState> uninstalledAppStates =
+                getUninstalledEphemeralAppStatesLPr(userId);
+        if (uninstalledAppStates == null || uninstalledAppStates.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        List<EphemeralApplicationInfo> uninstalledApps = new ArrayList<>();
+        final int stateCount = uninstalledAppStates.size();
+        for (int i = 0; i < stateCount; i++) {
+            UninstalledEphemeralAppState uninstalledAppState = uninstalledAppStates.get(i);
+            uninstalledApps.add(uninstalledAppState.mEphemeralApplicationInfo);
+        }
+        return uninstalledApps;
+    }
+
+    private void propagateEphemeralAppPermissionsIfNeeded(PackageParser.Package pkg, int userId) {
+        EphemeralApplicationInfo appInfo = getOrParseUninstalledEphemeralAppInfo(pkg.packageName, userId);
+        if (appInfo == null) {
+            return;
+        }
+        if (ArrayUtils.isEmpty(appInfo.getGrantedPermissions())) {
+            return;
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            for (String grantedPermission : appInfo.getGrantedPermissions()) {
+                mService.grantRuntimePermission(pkg.packageName, grantedPermission, userId);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    private EphemeralApplicationInfo getOrParseUninstalledEphemeralAppInfo(String packageName,
+            int userId) {
+        if (mUninstalledEphemeralApps != null) {
+            List<UninstalledEphemeralAppState> uninstalledAppStates =
+                    mUninstalledEphemeralApps.get(userId);
+            if (uninstalledAppStates != null) {
+                final int appCount = uninstalledAppStates.size();
+                for (int i = 0; i < appCount; i++) {
+                    UninstalledEphemeralAppState uninstalledAppState = uninstalledAppStates.get(i);
+                    if (uninstalledAppState.mEphemeralApplicationInfo
+                            .getPackageName().equals(packageName)) {
+                        return uninstalledAppState.mEphemeralApplicationInfo;
+                    }
+                }
+            }
+        }
+
+        File metadataFile = new File(getEphemeralApplicationDir(packageName, userId),
+                EPHEMERAL_APP_METADATA_FILE);
+        UninstalledEphemeralAppState uninstalledAppState = parseMetadataFile(metadataFile);
+        if (uninstalledAppState == null) {
+            return null;
+        }
+
+        return uninstalledAppState.mEphemeralApplicationInfo;
+    }
+
+    private List<UninstalledEphemeralAppState> getUninstalledEphemeralAppStatesLPr(int userId) {
+        List<UninstalledEphemeralAppState> uninstalledAppStates = null;
+        if (mUninstalledEphemeralApps != null) {
+            uninstalledAppStates = mUninstalledEphemeralApps.get(userId);
+            if (uninstalledAppStates != null) {
+                return uninstalledAppStates;
+            }
+        }
+
+        File ephemeralAppsDir = getEphemeralApplicationsDir(userId);
+        if (ephemeralAppsDir.exists()) {
+            File[] files = ephemeralAppsDir.listFiles();
+            if (files != null) {
+                for (File ephemeralDir : files) {
+                    if (!ephemeralDir.isDirectory()) {
+                        continue;
+                    }
+                    File metadataFile = new File(ephemeralDir,
+                            EPHEMERAL_APP_METADATA_FILE);
+                    UninstalledEphemeralAppState uninstalledAppState =
+                            parseMetadataFile(metadataFile);
+                    if (uninstalledAppState == null) {
+                        continue;
+                    }
+                    if (uninstalledAppStates == null) {
+                        uninstalledAppStates = new ArrayList<>();
+                    }
+                    uninstalledAppStates.add(uninstalledAppState);
+                }
+            }
+        }
+
+        if (uninstalledAppStates != null) {
+            if (mUninstalledEphemeralApps == null) {
+                mUninstalledEphemeralApps = new SparseArray<>();
+            }
+            mUninstalledEphemeralApps.put(userId, uninstalledAppStates);
+        }
+
+        return uninstalledAppStates;
+    }
+
+    private static boolean isValidCookie(Context context, byte[] cookie) {
+        if (ArrayUtils.isEmpty(cookie)) {
+            return true;
+        }
+        return cookie.length <= context.getPackageManager().getEphemeralCookieMaxSizeBytes();
+    }
+
+    private static UninstalledEphemeralAppState parseMetadataFile(File metadataFile) {
+        if (!metadataFile.exists()) {
+            return null;
+        }
+        FileInputStream in;
+        try {
+            in = new AtomicFile(metadataFile).openRead();
+        } catch (FileNotFoundException fnfe) {
+            Slog.i(LOG_TAG, "No ephemeral metadata file");
+            return null;
+        }
+
+        final File ephemeralDir = metadataFile.getParentFile();
+        final long timestamp = metadataFile.lastModified();
+        final String packageName = ephemeralDir.getName();
+
+        try {
+            XmlPullParser parser = Xml.newPullParser();
+            parser.setInput(in, StandardCharsets.UTF_8.name());
+            return new UninstalledEphemeralAppState(
+                    parseMetadata(parser, packageName), timestamp);
+        } catch (XmlPullParserException | IOException e) {
+            throw new IllegalStateException("Failed parsing ephemeral"
+                    + " metadata file: " + metadataFile, e);
+        } finally {
+            IoUtils.closeQuietly(in);
+        }
+    }
+
+    private static File computeEphemeralCookieFile(PackageParser.Package pkg, int userId) {
+        File appDir = getEphemeralApplicationDir(pkg.packageName, userId);
+        String cookieFile = EPHEMERAL_APP_COOKIE_FILE_PREFIX + computePackageCertDigest(pkg)
+                + EPHEMERAL_APP_COOKIE_FILE_SIFFIX;
+        return new File(appDir, cookieFile);
+    }
+
+    private static File peekEphemeralCookieFile(String packageName, int userId) {
+        File appDir = getEphemeralApplicationDir(packageName, userId);
+        if (!appDir.exists()) {
+            return null;
+        }
+        for (File file : appDir.listFiles()) {
+            if (!file.isDirectory()
+                    && file.getName().startsWith(EPHEMERAL_APP_COOKIE_FILE_PREFIX)
+                    && file.getName().endsWith(EPHEMERAL_APP_COOKIE_FILE_SIFFIX)) {
+                return file;
+            }
+        }
+        return null;
+    }
+
+    private static EphemeralApplicationInfo parseMetadata(XmlPullParser parser, String packageName)
+            throws IOException, XmlPullParserException {
+        final int outerDepth = parser.getDepth();
+        while (XmlUtils.nextElementWithin(parser, outerDepth)) {
+            if (TAG_PACKAGE.equals(parser.getName())) {
+                return parsePackage(parser, packageName);
+            }
+        }
+        return null;
+    }
+
+    private static EphemeralApplicationInfo parsePackage(XmlPullParser parser, String packageName)
+            throws IOException, XmlPullParserException {
+        String label = parser.getAttributeValue(null, ATTR_LABEL);
+
+        List<String> outRequestedPermissions = new ArrayList<>();
+        List<String> outGrantedPermissions = new ArrayList<>();
+
+        final int outerDepth = parser.getDepth();
+        while (XmlUtils.nextElementWithin(parser, outerDepth)) {
+            if (TAG_PERMS.equals(parser.getName())) {
+                parsePermissions(parser, outRequestedPermissions, outGrantedPermissions);
+            }
+        }
+
+        String[] requestedPermissions = new String[outRequestedPermissions.size()];
+        outRequestedPermissions.toArray(requestedPermissions);
+
+        String[] grantedPermissions = new String[outGrantedPermissions.size()];
+        outGrantedPermissions.toArray(grantedPermissions);
+
+        return new EphemeralApplicationInfo(packageName, label,
+                requestedPermissions, grantedPermissions);
+    }
+
+    private static void parsePermissions(XmlPullParser parser, List<String> outRequestedPermissions,
+            List<String> outGrantedPermissions) throws IOException, XmlPullParserException {
+        final int outerDepth = parser.getDepth();
+        while (XmlUtils.nextElementWithin(parser,outerDepth)) {
+            if (TAG_PERM.equals(parser.getName())) {
+                String permission = XmlUtils.readStringAttribute(parser, ATTR_NAME);
+                outRequestedPermissions.add(permission);
+                if (XmlUtils.readBooleanAttribute(parser, ATTR_GRANTED)) {
+                    outGrantedPermissions.add(permission);
+                }
+            }
+        }
+    }
+
+    private void writeUninstalledEphemeralAppMetadata(
+            EphemeralApplicationInfo ephemeralApp, int userId) {
+        File appDir = getEphemeralApplicationDir(ephemeralApp.getPackageName(), userId);
+        if (!appDir.exists() && !appDir.mkdirs()) {
+            return;
+        }
+
+        File metadataFile = new File(appDir, EPHEMERAL_APP_METADATA_FILE);
+
+        AtomicFile destination = new AtomicFile(metadataFile);
+        FileOutputStream out = null;
+        try {
+            out = destination.startWrite();
+
+            XmlSerializer serializer = Xml.newSerializer();
+            serializer.setOutput(out, StandardCharsets.UTF_8.name());
+            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+
+            serializer.startDocument(null, true);
+
+            serializer.startTag(null, TAG_PACKAGE);
+            serializer.attribute(null, ATTR_LABEL, ephemeralApp.loadLabel(
+                    mService.mContext.getPackageManager()).toString());
+
+            serializer.startTag(null, TAG_PERMS);
+            for (String permission : ephemeralApp.getRequestedPermissions()) {
+                serializer.startTag(null, TAG_PERM);
+                serializer.attribute(null, ATTR_NAME, permission);
+                if (ArrayUtils.contains(ephemeralApp.getGrantedPermissions(), permission)) {
+                    serializer.attribute(null, ATTR_GRANTED, String.valueOf(true));
+                }
+                serializer.endTag(null, TAG_PERM);
+            }
+            serializer.endTag(null, TAG_PERMS);
+
+            serializer.endTag(null, TAG_PACKAGE);
+
+            serializer.endDocument();
+            destination.finishWrite(out);
+        } catch (Throwable t) {
+            Slog.wtf(LOG_TAG, "Failed to write ephemeral state, restoring backup", t);
+            destination.failWrite(out);
+        } finally {
+            IoUtils.closeQuietly(out);
+        }
+    }
+
+    private static String computePackageCertDigest(PackageParser.Package pkg) {
+        MessageDigest messageDigest;
+        try {
+            messageDigest = MessageDigest.getInstance("SHA256");
+        } catch (NoSuchAlgorithmException e) {
+            /* can't happen */
+            return null;
+        }
+
+        messageDigest.update(pkg.mSignatures[0].toByteArray());
+
+        final byte[] digest = messageDigest.digest();
+        final int digestLength = digest.length;
+        final int charCount = 2 * digestLength;
+
+        final char[] chars = new char[charCount];
+        for (int i = 0; i < digestLength; i++) {
+            final int byteHex = digest[i] & 0xFF;
+            chars[i * 2] = HEX_ARRAY[byteHex >>> 4];
+            chars[i * 2 + 1] = HEX_ARRAY[byteHex & 0x0F];
+        }
+        return new String(chars);
+    }
+
+    private static File getEphemeralApplicationsDir(int userId) {
+        return new File(Environment.getUserSystemDirectory(userId),
+                EPHEMERAL_APPS_FOLDER);
+    }
+
+    private static File getEphemeralApplicationDir(String packageName, int userId) {
+        return new File (getEphemeralApplicationsDir(userId), packageName);
+    }
+
+    private static void deleteDir(File dir) {
+        File[] files = dir.listFiles();
+        if (files != null) {
+            for (File file : dir.listFiles()) {
+                deleteDir(file);
+            }
+        }
+        dir.delete();
+    }
+
+    private static final class UninstalledEphemeralAppState {
+        final EphemeralApplicationInfo mEphemeralApplicationInfo;
+        final long mTimestamp;
+
+        public UninstalledEphemeralAppState(EphemeralApplicationInfo ephemeralApp,
+                long timestamp) {
+            mEphemeralApplicationInfo = ephemeralApp;
+            mTimestamp = timestamp;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 4f04519..3a8a988 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -34,7 +34,6 @@
 import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
 import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
-import static android.content.pm.PackageManager.INSTALL_FAILED_DEXOPT;
 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
 import static android.content.pm.PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID;
@@ -94,8 +93,6 @@
 import android.app.IActivityManager;
 import android.app.admin.IDevicePolicyManager;
 import android.app.backup.IBackupManager;
-import android.app.usage.UsageStats;
-import android.app.usage.UsageStatsManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -108,6 +105,7 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.AppsQueryHelper;
+import android.content.pm.EphemeralApplicationInfo;
 import android.content.pm.FeatureInfo;
 import android.content.pm.IOnPermissionsChangeListener;
 import android.content.pm.IPackageDataObserver;
@@ -147,6 +145,7 @@
 import android.content.pm.VerifierDeviceIdentity;
 import android.content.pm.VerifierInfo;
 import android.content.res.Resources;
+import android.graphics.Bitmap;
 import android.hardware.display.DisplayManager;
 import android.net.Uri;
 import android.os.Debug;
@@ -203,6 +202,7 @@
 import android.util.Xml;
 import android.view.Display;
 
+import com.android.internal.annotations.GuardedBy;
 import dalvik.system.DexFile;
 import dalvik.system.VMRuntime;
 
@@ -210,7 +210,6 @@
 import libcore.util.EmptyArray;
 
 import com.android.internal.R;
-import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.EphemeralResolveInfo;
 import com.android.internal.app.IMediaContainerService;
 import com.android.internal.app.ResolverActivity;
@@ -515,6 +514,8 @@
     // If a recursive restorecon of /data/data/<pkg> is needed.
     private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon();
 
+    private final EphemeralApplicationRegistry mEphemeralApplicationRegistry;
+
     public static final class SharedLibraryEntry {
         public final String path;
         public final String apk;
@@ -1399,6 +1400,10 @@
                                         args.installGrantPermissions);
                             }
 
+                            synchronized (mPackages) {
+                                mEphemeralApplicationRegistry.onPackageInstalledLPw(res.pkg);
+                            }
+
                             // Determine the set of users who are adding this
                             // package for the first time vs. those who are seeing
                             // an update.
@@ -2408,6 +2413,8 @@
                 mEphemeralInstallerComponent = null;
                 mEphemeralResolverConnection = null;
             }
+
+            mEphemeralApplicationRegistry = new EphemeralApplicationRegistry(this);
         } // synchronized (mPackages)
         } // synchronized (mInstallLock)
 
@@ -4093,8 +4100,15 @@
     @Override
     public boolean isProtectedBroadcast(String actionName) {
         synchronized (mPackages) {
-            return mProtectedBroadcasts.contains(actionName);
+            if (mProtectedBroadcasts.contains(actionName)) {
+                return true;
+            } else if (actionName != null
+                    && actionName.startsWith("android.net.netmon.lingerExpired")) {
+                // TODO: remove this terrible hack
+                return true;
+            }
         }
+        return false;
     }
 
     @Override
@@ -5780,6 +5794,82 @@
         }
     }
 
+    @Override
+    public ParceledListSlice<EphemeralApplicationInfo> getEphemeralApplications(int userId) {
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS,
+                "getEphemeralApplications");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
+                "getEphemeralApplications");
+        synchronized (mPackages) {
+            List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry
+                    .getEphemeralApplicationsLPw(userId);
+            if (ephemeralApps != null) {
+                return new ParceledListSlice<>(ephemeralApps);
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public boolean isEphemeralApplication(String packageName, int userId) {
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
+                "isEphemeral");
+        if (!isCallerSameApp(packageName)) {
+            return false;
+        }
+        synchronized (mPackages) {
+            PackageParser.Package pkg = mPackages.get(packageName);
+            if (pkg != null) {
+                return pkg.applicationInfo.isEphemeralApp();
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public byte[] getEphemeralApplicationCookie(String packageName, int userId) {
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
+                "getCookie");
+        if (!isCallerSameApp(packageName)) {
+            return null;
+        }
+        synchronized (mPackages) {
+            return mEphemeralApplicationRegistry.getEphemeralApplicationCookieLPw(
+                    packageName, userId);
+        }
+    }
+
+    @Override
+    public boolean setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId) {
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
+                "setCookie");
+        if (!isCallerSameApp(packageName)) {
+            return false;
+        }
+        synchronized (mPackages) {
+            return mEphemeralApplicationRegistry.setEphemeralApplicationCookieLPw(
+                    packageName, cookie, userId);
+        }
+    }
+
+    @Override
+    public Bitmap getEphemeralApplicationIcon(String packageName, int userId) {
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS,
+                "getEphemeralApplicationIcon");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
+                "getEphemeralApplicationIcon");
+        synchronized (mPackages) {
+            return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw(
+                    packageName, userId);
+        }
+    }
+
+    private boolean isCallerSameApp(String packageName) {
+        PackageParser.Package pkg = mPackages.get(packageName);
+        return pkg != null
+                && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid;
+    }
+
     public List<ApplicationInfo> getPersistentApplications(int flags) {
         final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
 
@@ -9707,6 +9797,15 @@
             if (r1.system != r2.system) {
                 return r1.system ? -1 : 1;
             }
+            if (r1.activityInfo != null) {
+                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
+            }
+            if (r1.serviceInfo != null) {
+                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
+            }
+            if (r1.providerInfo != null) {
+                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
+            }
             return 0;
         }
     };
@@ -12266,8 +12365,7 @@
         // First find the old package info and check signatures
         synchronized(mPackages) {
             oldPackage = mPackages.get(pkgName);
-            final boolean oldIsEphemeral
-                    = ((oldPackage.applicationInfo.flags & ApplicationInfo.FLAG_EPHEMERAL) != 0);
+            final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp();
             if (isEphemeral && !oldIsEphemeral) {
                 // can't downgrade from full to ephemeral
                 Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName);
@@ -13086,11 +13184,11 @@
     }
 
     private static boolean isEphemeral(PackageParser.Package pkg) {
-        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EPHEMERAL) != 0;
+        return pkg.applicationInfo.isEphemeralApp();
     }
 
     private static boolean isEphemeral(PackageSetting ps) {
-        return (ps.pkgFlags & ApplicationInfo.FLAG_EPHEMERAL) != 0;
+        return ps.pkg != null && isEphemeral(ps.pkg);
     }
 
     private static boolean isSystemApp(PackageParser.Package pkg) {
@@ -13291,11 +13389,14 @@
         boolean removedForAllUsers = false;
         boolean systemUpdate = false;
 
+        PackageParser.Package uninstalledPkg;
+
         // for the uninstall-updates case and restricted profiles, remember the per-
         // userhandle installed state
         int[] allUsers;
         boolean[] perUserInstalled;
         synchronized (mPackages) {
+            uninstalledPkg = mPackages.get(packageName);
             PackageSetting ps = mSettings.mPackages.get(packageName);
             allUsers = sUserManager.getUserIds();
             perUserInstalled = new boolean[allUsers.length];
@@ -13310,8 +13411,13 @@
                     true, allUsers, perUserInstalled,
                     flags | REMOVE_CHATTY, info, true);
             systemUpdate = info.isRemovedPackageSystemUpdate;
-            if (res && !systemUpdate && mPackages.get(packageName) == null) {
-                removedForAllUsers = true;
+            synchronized (mPackages) {
+                if (res) {
+                    if (!systemUpdate && mPackages.get(packageName) == null) {
+                        removedForAllUsers = true;
+                    }
+                    mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPkg);
+                }
             }
             if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate
                     + " removedForAllUsers=" + removedForAllUsers);
@@ -16446,7 +16552,7 @@
             if (userDir.exists()) continue;
 
             try {
-                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber);
+                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, user.isEphemeral());
                 UserManagerService.enforceSerialNumber(userDir, user.serialNumber);
             } catch (IOException e) {
                 Log.wtf(TAG, "Failed to create user directory on " + volumeUuid, e);
@@ -16833,15 +16939,14 @@
             mUserNeedsBadging.delete(userHandle);
             mSettings.removeUserLPw(userHandle);
             mPendingBroadcasts.remove(userHandle);
+            mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle);
         }
         synchronized (mInstallLock) {
-            if (mInstaller != null) {
-                final StorageManager storage = mContext.getSystemService(StorageManager.class);
-                for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
-                    final String volumeUuid = vol.getFsUuid();
-                    if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid);
-                    mInstaller.removeUserDataDirs(volumeUuid, userHandle);
-                }
+            final StorageManager storage = mContext.getSystemService(StorageManager.class);
+            for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
+                final String volumeUuid = vol.getFsUuid();
+                if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid);
+                mInstaller.removeUserDataDirs(volumeUuid, userHandle);
             }
             synchronized (mPackages) {
                 removeUnusedPackagesLILPw(userManager, userHandle);
@@ -16903,17 +17008,13 @@
 
     /** Called by UserManagerService */
     void createNewUser(int userHandle) {
-        if (mInstaller != null) {
-            synchronized (mInstallLock) {
-                synchronized (mPackages) {
-                    mInstaller.createUserConfig(userHandle);
-                    mSettings.createNewUserLILPw(this, mInstaller, userHandle);
-                }
-            }
-            synchronized (mPackages) {
-                applyFactoryDefaultBrowserLPw(userHandle);
-                primeDomainVerificationsLPw(userHandle);
-            }
+        synchronized (mInstallLock) {
+            mInstaller.createUserConfig(userHandle);
+            mSettings.createNewUserLI(this, mInstaller, userHandle);
+        }
+        synchronized (mPackages) {
+            applyFactoryDefaultBrowserLPw(userHandle);
+            primeDomainVerificationsLPw(userHandle);
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index f9ed760..b18c846 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -103,11 +103,11 @@
                     return runUninstall();
                 case "resolve-activity":
                     return runResolveActivity();
-                case "query-intent-activities":
+                case "query-activities":
                     return runQueryIntentActivities();
-                case "query-intent-services":
+                case "query-services":
                     return runQueryIntentServices();
-                case "query-intent-receivers":
+                case "query-receivers":
                     return runQueryIntentReceivers();
                 default:
                     return handleDefaultCommands(cmd);
@@ -1043,13 +1043,13 @@
         pw.println("      -s: short summary");
         pw.println("      -d: only list dangerous permissions");
         pw.println("      -u: list only the permissions users will see");
-        pw.println("  resolve-intent [--user USER_ID] INTENT");
+        pw.println("  resolve-activity [--user USER_ID] INTENT");
         pw.println("    Prints the activity that resolves to the given Intent.");
-        pw.println("  query-intent-activities [--user USER_ID] INTENT");
+        pw.println("  query-activities [--user USER_ID] INTENT");
         pw.println("    Prints all activities that can handle the given Intent.");
-        pw.println("  query-intent-services [--user USER_ID] INTENT");
+        pw.println("  query-services [--user USER_ID] INTENT");
         pw.println("    Prints all services that can handle the given Intent.");
-        pw.println("  query-intent-receivers [--user USER_ID] INTENT");
+        pw.println("  query-receivers [--user USER_ID] INTENT");
         pw.println("    Prints all broadcast receivers that can handle the given Intent.");
         pw.println();
         Intent.printIntentArgsHelp(pw , "");
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 99aa30b..22f8e96 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -3644,21 +3644,47 @@
         }
     }
 
-    void createNewUserLILPw(PackageManagerService service, Installer installer, int userHandle) {
-        for (PackageSetting ps : mPackages.values()) {
-            if (ps.pkg == null || ps.pkg.applicationInfo == null) {
+    void createNewUserLI(@NonNull PackageManagerService service, @NonNull Installer installer,
+            int userHandle) {
+        String[] volumeUuids;
+        String[] names;
+        int[] uids;
+        String[] seinfos;
+        int packagesCount;
+        synchronized (mPackages) {
+            Collection<PackageSetting> packages = mPackages.values();
+            packagesCount = packages.size();
+            volumeUuids = new String[packagesCount];
+            names = new String[packagesCount];
+            uids = new int[packagesCount];
+            seinfos = new String[packagesCount];
+            Iterator<PackageSetting> packagesIterator = packages.iterator();
+            for (int i = 0; i < packagesCount; i++) {
+                PackageSetting ps = packagesIterator.next();
+                if (ps.pkg == null || ps.pkg.applicationInfo == null) {
+                    continue;
+                }
+                // Only system apps are initially installed.
+                ps.setInstalled(ps.isSystem(), userHandle);
+                // Need to create a data directory for all apps under this user. Accumulate all
+                // required args and call the installer after mPackages lock has been released
+                volumeUuids[i] = ps.volumeUuid;
+                names[i] = ps.name;
+                uids[i] = UserHandle.getUid(userHandle, ps.appId);
+                seinfos[i] = ps.pkg.applicationInfo.seinfo;
+            }
+        }
+        for (int i = 0; i < packagesCount; i++) {
+            if (names[i] == null) {
                 continue;
             }
-            // Only system apps are initially installed.
-            ps.setInstalled((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0, userHandle);
-            // Need to create a data directory for all apps under this user.
-            installer.createUserData(ps.volumeUuid, ps.name,
-                    UserHandle.getUid(userHandle, ps.appId), userHandle,
-                    ps.pkg.applicationInfo.seinfo);
+            installer.createUserData(volumeUuids[i], names[i], uids[i], userHandle, seinfos[i]);
         }
-        applyDefaultPreferredAppsLPw(service, userHandle);
-        writePackageRestrictionsLPr(userHandle);
-        writePackageListLPr(userHandle);
+        synchronized (mPackages) {
+            applyDefaultPreferredAppsLPw(service, userHandle);
+            writePackageRestrictionsLPr(userHandle);
+            writePackageListLPr(userHandle);
+        }
     }
 
     void removeUserLPw(int userId) {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index b859915..0b59c16 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -16,6 +16,7 @@
 
 package com.android.server.pm;
 
+import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Activity;
@@ -58,6 +59,7 @@
 import android.system.OsConstants;
 import android.util.AtomicFile;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
@@ -90,6 +92,7 @@
 import java.util.List;
 
 import libcore.io.IoUtils;
+import libcore.util.Objects;
 
 /**
  * Service for {@link UserManager}.
@@ -107,6 +110,7 @@
     private static final boolean DBG_WITH_STACKTRACE = false; // DO NOT SUBMIT WITH TRUE
 
     private static final String TAG_NAME = "name";
+    private static final String TAG_ACCOUNT = "account";
     private static final String ATTR_FLAGS = "flags";
     private static final String ATTR_ICON_PATH = "icon";
     private static final String ATTR_ID = "id";
@@ -178,6 +182,14 @@
     private final SparseArray<UserInfo> mUsers = new SparseArray<>();
 
     /**
+     * This collection contains each user's account name if the user chose to set one up
+     * during the initial user creation process.  Keeping this information separate from mUsers
+     * to avoid accidentally leak it.
+     */
+    @GuardedBy("mUsersLock")
+    private final SparseArray<String> mUserAccounts = new SparseArray<>();
+
+    /**
      * User restrictions set via UserManager.  This doesn't include restrictions set by
      * device owner / profile owners.
      *
@@ -306,13 +318,13 @@
     }
 
     void systemReady() {
-        // Prune out any partially created/partially removed users.
+        // Prune out any partially created, partially removed and ephemeral users.
         ArrayList<UserInfo> partials = new ArrayList<>();
         synchronized (mUsersLock) {
             final int userSize = mUsers.size();
             for (int i = 0; i < userSize; i++) {
                 UserInfo ui = mUsers.valueAt(i);
-                if ((ui.partial || ui.guestToRemove) && i != 0) {
+                if ((ui.partial || ui.guestToRemove || ui.isEphemeral()) && i != 0) {
                     partials.add(ui);
                 }
             }
@@ -336,6 +348,33 @@
     }
 
     @Override
+    public String getUserAccount(int userId) {
+        checkManageUserAndAcrossUsersFullPermission("get user account");
+        synchronized (mUsersLock) {
+            return mUserAccounts.get(userId);
+        }
+    }
+
+    @Override
+    public void setUserAccount(int userId, String accountName) {
+        checkManageUserAndAcrossUsersFullPermission("set user account");
+        UserInfo userToUpdate = null;
+        synchronized (mPackagesLock) {
+            synchronized (mUsersLock) {
+                String currentAccount = mUserAccounts.get(userId);
+                if (!Objects.equal(currentAccount, accountName)) {
+                    mUserAccounts.put(userId, accountName);
+                    userToUpdate = mUsers.get(userId);
+                }
+            }
+
+            if (userToUpdate != null) {
+                writeUserLP(userToUpdate);
+            }
+        }
+    }
+
+    @Override
     public UserInfo getPrimaryUser() {
         checkManageUsersPermission("query users");
         synchronized (mUsersLock) {
@@ -475,6 +514,66 @@
                 && user.profileGroupId == profile.profileGroupId);
     }
 
+    private void broadcastProfileAvailabilityChanges(UserHandle profileHandle,
+            UserHandle parentHandle, Bundle extras) {
+        // Send intent to profile
+        Intent intent = new Intent(Intent.ACTION_AVAILABILITY_CHANGED);
+        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+        intent.putExtras(extras);
+        mContext.sendBroadcastAsUser(intent, profileHandle);
+
+        // Send intent to parent
+        if (parentHandle != null) {
+            intent = new Intent(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED);
+            intent.putExtra(Intent.EXTRA_USER, profileHandle);
+            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+            intent.putExtras(extras);
+            mContext.sendBroadcastAsUser(intent, parentHandle);
+        }
+    }
+
+    @Override
+    public void setQuietModeEnabled(int userHandle, boolean enableQuietMode) {
+        checkManageUsersPermission("silence profile");
+        boolean changed = false;
+        UserInfo profile, parent;
+        synchronized (mPackagesLock) {
+            synchronized (mUsersLock) {
+                profile = getUserInfoLU(userHandle);
+                parent = getProfileParentLU(userHandle);
+
+            }
+            if (profile == null || !profile.isManagedProfile()) {
+                throw new IllegalArgumentException("User " + userHandle + " is not a profile");
+            }
+            if (profile.isQuietModeEnabled() != enableQuietMode) {
+                profile.flags ^= UserInfo.FLAG_QUIET_MODE;
+                writeUserLP(profile);
+                changed = true;
+            }
+        }
+        if (changed) {
+            Bundle extras = new Bundle();
+            extras.putBoolean(Intent.EXTRA_QUIET_MODE, enableQuietMode);
+            broadcastProfileAvailabilityChanges(profile.getUserHandle(),
+                    parent != null ? parent.getUserHandle() : null, extras);
+        }
+    }
+
+    @Override
+    public boolean isQuietModeEnabled(int userHandle) {
+        synchronized (mPackagesLock) {
+            UserInfo info;
+            synchronized (mUsersLock) {
+                info = getUserInfoLU(userHandle);
+            }
+            if (info == null || !info.isManagedProfile()) {
+                throw new IllegalArgumentException("User " + userHandle + " is not a profile");
+            }
+            return info.isQuietModeEnabled();
+        }
+    }
+
     @Override
     public void setUserEnabled(int userId) {
         checkManageUsersPermission("enable user");
@@ -785,6 +884,15 @@
     }
 
     @Override
+    public boolean hasBaseUserRestriction(String restrictionKey, int userId) {
+        checkManageUsersPermission("hasBaseUserRestriction");
+        synchronized (mRestrictionsLock) {
+            Bundle bundle = mBaseUserRestrictions.get(userId);
+            return (bundle != null && bundle.getBoolean(restrictionKey, false));
+        }
+    }
+
+    @Override
     public void setUserRestriction(String key, boolean value, int userId) {
         checkManageUsersPermission("setUserRestriction");
         synchronized (mRestrictionsLock) {
@@ -983,6 +1091,30 @@
 
     /**
      * Enforces that only the system UID or root's UID or apps that have the
+     * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} and
+     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL INTERACT_ACROSS_USERS_FULL}
+     * permissions can make certain calls to the UserManager.
+     *
+     * @param message used as message if SecurityException is thrown
+     * @throws SecurityException if the caller does not have enough privilege.
+     */
+    private static final void checkManageUserAndAcrossUsersFullPermission(String message) {
+        final int uid = Binder.getCallingUid();
+        if (uid != Process.SYSTEM_UID && uid != 0
+                && ActivityManager.checkComponentPermission(
+                Manifest.permission.MANAGE_USERS,
+                uid, -1, true) != PackageManager.PERMISSION_GRANTED
+                && ActivityManager.checkComponentPermission(
+                Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+                uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException(
+                    "You need MANAGE_USERS and INTERACT_ACROSS_USERS_FULL permission to: "
+                            + message);
+        }
+    }
+
+    /**
+     * Enforces that only the system UID or root's UID or apps that have the
      * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS}
      * permission can make certain calls to the UserManager.
      *
@@ -999,13 +1131,6 @@
         }
     }
 
-    private static void checkSystemOrRoot(String message) {
-        final int uid = Binder.getCallingUid();
-        if (uid != Process.SYSTEM_UID && uid != 0) {
-            throw new SecurityException("Only system may call: " + message);
-        }
-    }
-
     private void writeBitmapLP(UserInfo info, Bitmap bitmap) {
         try {
             File dir = new File(mUsersDir, Integer.toString(info.id));
@@ -1087,11 +1212,14 @@
                     final String name = parser.getName();
                     if (name.equals(TAG_USER)) {
                         String id = parser.getAttributeValue(null, ATTR_ID);
-                        UserInfo user = readUserLP(Integer.parseInt(id));
+                        Pair<UserInfo, String> userPair = readUserLP(Integer.parseInt(id));
 
-                        if (user != null) {
+                        if (userPair != null) {
+                            UserInfo user = userPair.first;
+                            String account = userPair.second;
                             synchronized (mUsersLock) {
                                 mUsers.put(user.id, user);
+                                mUserAccounts.put(user.id, account);
                                 if (mNextSerialNumber < 0 || mNextSerialNumber <= user.id) {
                                     mNextSerialNumber = user.id + 1;
                                 }
@@ -1291,6 +1419,17 @@
                         mDevicePolicyLocalUserRestrictions.get(userInfo.id),
                         TAG_DEVICE_POLICY_RESTRICTIONS);
             }
+            // Update the account field if it is set.
+            String account;
+            synchronized (mUsersLock) {
+                account = mUserAccounts.get(userInfo.id);
+            }
+            if (account != null) {
+                serializer.startTag(null, TAG_ACCOUNT);
+                serializer.text(account);
+                serializer.endTag(null, TAG_ACCOUNT);
+            }
+
             serializer.endTag(null, TAG_USER);
 
             serializer.endDocument();
@@ -1363,10 +1502,11 @@
         }
     }
 
-    private UserInfo readUserLP(int id) {
+    private Pair<UserInfo, String> readUserLP(int id) {
         int flags = 0;
         int serialNumber = id;
         String name = null;
+        String account = null;
         String iconPath = null;
         long creationTime = 0L;
         long lastLoggedInTime = 0L;
@@ -1435,6 +1575,11 @@
                         UserRestrictionsUtils.readRestrictions(parser, baseRestrictions);
                     } else if (TAG_DEVICE_POLICY_RESTRICTIONS.equals(tag)) {
                         UserRestrictionsUtils.readRestrictions(parser, localRestrictions);
+                    } else if (TAG_ACCOUNT.equals(tag)) {
+                        type = parser.next();
+                        if (type == XmlPullParser.TEXT) {
+                            account = parser.getText();
+                        }
                     }
                 }
             }
@@ -1451,7 +1596,7 @@
                 mBaseUserRestrictions.put(id, baseRestrictions);
                 mDevicePolicyLocalUserRestrictions.put(id, localRestrictions);
             }
-            return userInfo;
+            return new Pair<>(userInfo, account);
 
         } catch (IOException ioe) {
         } catch (XmlPullParserException pe) {
@@ -1606,6 +1751,10 @@
                         }
                     }
                 }
+
+                if (parent != null && parent.isEphemeral()) {
+                    flags |= UserInfo.FLAG_EPHEMERAL;
+                }
                 userId = getNextAvailableId();
                 userInfo = new UserInfo(userId, name, null, flags);
                 userInfo.serialNumber = mNextSerialNumber++;
@@ -1634,12 +1783,13 @@
                 }
             }
             final StorageManager storage = mContext.getSystemService(StorageManager.class);
-            storage.createUserKey(userId, userInfo.serialNumber);
+            storage.createUserKey(userId, userInfo.serialNumber, userInfo.isEphemeral());
             for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
                 final String volumeUuid = vol.getFsUuid();
                 try {
                     final File userDir = Environment.getDataUserDirectory(volumeUuid, userId);
-                    storage.prepareUserStorage(volumeUuid, userId, userInfo.serialNumber);
+                    storage.prepareUserStorage(
+                            volumeUuid, userId, userInfo.serialNumber, userInfo.isEphemeral());
                     enforceSerialNumber(userDir, userInfo.serialNumber);
                 } catch (IOException e) {
                     Log.wtf(LOG_TAG, "Failed to create user directory on " + volumeUuid, e);
@@ -1873,6 +2023,7 @@
         // Remove this user from the list
         synchronized (mUsersLock) {
             mUsers.remove(userHandle);
+            mUserAccounts.delete(userHandle);
             mIsUserManaged.delete(userHandle);
         }
         synchronized (mRestrictionsLock) {
@@ -2433,6 +2584,11 @@
                                 pw, "      ", mCachedEffectiveUserRestrictions.get(user.id));
                     }
                     pw.println();
+                    String accountName = mUserAccounts.get(userId);
+                    if (accountName != null) {
+                        pw.print("    Account name: " + accountName);
+                        pw.println();
+                    }
                 }
             }
             pw.println("  Device policy global restrictions:");
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 816903e..9bbc3c1 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -209,11 +209,13 @@
     }
 
     /**
-     * @return true if a restriction is settable by profile owner.
+     * @return true if a restriction is settable by profile owner.  Note it takes a user ID because
+     * some restrictions can be changed by PO only when it's running on the system user.
      */
-    public static boolean canProfileOwnerChange(String restriction) {
-        return !(IMMUTABLE_BY_OWNERS.contains(restriction)
-                || DEVICE_OWNER_ONLY_RESTRICTIONS.contains(restriction));
+    public static boolean canProfileOwnerChange(String restriction, int userId) {
+        return !IMMUTABLE_BY_OWNERS.contains(restriction)
+                && !(userId != UserHandle.USER_SYSTEM
+                    && DEVICE_OWNER_ONLY_RESTRICTIONS.contains(restriction));
     }
 
     /**
diff --git a/services/core/java/com/android/server/policy/GlobalActions.java b/services/core/java/com/android/server/policy/GlobalActions.java
index d160221f..c8523c9 100644
--- a/services/core/java/com/android/server/policy/GlobalActions.java
+++ b/services/core/java/com/android/server/policy/GlobalActions.java
@@ -390,9 +390,10 @@
                                 // screenshot.
                                 mHandler.postDelayed(new Runnable() {
                                     @Override public void run() {
+                                        //  TODO: select 'progress' flag according to menu choice
                                         try {
                                             ActivityManagerNative.getDefault()
-                                                    .requestBugReport();
+                                                    .requestBugReport(true);
                                         } catch (RemoteException e) {
                                         }
                                     }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index fe427d3..b9a9d6e 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -396,6 +396,7 @@
     boolean mDeskDockEnablesAccelerometer;
     int mLidKeyboardAccessibility;
     int mLidNavigationAccessibility;
+    boolean mLidControlsScreenLock;
     boolean mLidControlsSleep;
     int mShortPressOnPowerBehavior;
     int mLongPressOnPowerBehavior;
@@ -1440,6 +1441,8 @@
                 com.android.internal.R.integer.config_lidKeyboardAccessibility);
         mLidNavigationAccessibility = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_lidNavigationAccessibility);
+        mLidControlsScreenLock = mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_lidControlsScreenLock);
         mLidControlsSleep = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_lidControlsSleep);
         mTranslucentDecorEnabled = mContext.getResources().getBoolean(
@@ -6378,6 +6381,8 @@
             mPowerManager.goToSleep(SystemClock.uptimeMillis(),
                     PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH,
                     PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
+        } else if (mLidState == LID_CLOSED && mLidControlsScreenLock) {
+            mWindowManagerFuncs.lockDeviceNow();
         }
 
         synchronized (mLock) {
@@ -6970,6 +6975,7 @@
         pw.print(prefix); pw.print("mLidKeyboardAccessibility=");
                 pw.print(mLidKeyboardAccessibility);
                 pw.print(" mLidNavigationAccessibility="); pw.print(mLidNavigationAccessibility);
+                pw.print(" mLidControlsScreenLock="); pw.println(mLidControlsScreenLock);
                 pw.print(" mLidControlsSleep="); pw.println(mLidControlsSleep);
         pw.print(prefix);
                 pw.print("mShortPressOnPowerBehavior="); pw.print(mShortPressOnPowerBehavior);
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index a4b4276..e6b649e7 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -16,6 +16,9 @@
 
 package com.android.server.wm;
 
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.app.Service;
@@ -219,7 +222,7 @@
      */
     private static final class DisplayMagnifier {
 
-        private static final String LOG_TAG = "DisplayMagnifier";
+        private static final String LOG_TAG = TAG_WITH_CLASS_NAME ? "DisplayMagnifier" : TAG_WM;
 
         private static final boolean DEBUG_WINDOW_TRANSITIONS = false;
         private static final boolean DEBUG_ROTATION = false;
@@ -925,7 +928,8 @@
      * user can see on the screen.
      */
     private static final class WindowsForAccessibilityObserver {
-        private static final String LOG_TAG = "WindowsForAccessibilityObserver";
+        private static final String LOG_TAG = TAG_WITH_CLASS_NAME ?
+                "WindowsForAccessibilityObserver" : TAG_WM;
 
         private static final boolean DEBUG = false;
 
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index d394125..a7a4ed1 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -39,6 +39,8 @@
 import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
 import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation;
 import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 import android.annotation.Nullable;
 import android.content.Context;
@@ -46,7 +48,6 @@
 import android.graphics.Bitmap;
 import android.graphics.Rect;
 import android.os.Debug;
-import android.os.Handler;
 import android.os.IBinder;
 import android.os.IRemoteCallback;
 import android.os.RemoteException;
@@ -73,6 +74,7 @@
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
@@ -82,10 +84,10 @@
 // mOpeningApps and mClosingApps are the lists of tokens that will be
 // made visible or hidden at the next transition.
 public class AppTransition implements Dump {
-    private static final String TAG = "AppTransition";
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "AppTransition" : TAG_WM;
     private static final boolean DEBUG_APP_TRANSITIONS =
-            WindowManagerService.DEBUG_APP_TRANSITIONS;
-    private static final boolean DEBUG_ANIM = WindowManagerService.DEBUG_ANIM;
+            WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
+    private static final boolean DEBUG_ANIM = WindowManagerDebugConfig.DEBUG_ANIM;
     private static final int CLIP_REVEAL_TRANSLATION_Y_DP = 8;
 
     /** Not set up for a transition. */
@@ -308,6 +310,16 @@
         return mNextAppTransitionScaleUp;
     }
 
+    boolean isNextAppTransitionThumbnailUp() {
+        return mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP ||
+                mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP;
+    }
+
+    boolean isNextAppTransitionThumbnailDown() {
+        return mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN ||
+                mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
+    }
+
     /**
      * @return true if and only if we are currently fetching app transition specs from the future
      *         passed into {@link #overridePendingAppTransitionMultiThumbFuture}
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index 4861acc..ab47f07 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -16,9 +16,12 @@
 
 package com.android.server.wm;
 
-import static com.android.server.wm.WindowManagerService.DEBUG_ANIM;
-import static com.android.server.wm.WindowManagerService.DEBUG_LAYERS;
-import static com.android.server.wm.WindowManagerService.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET;
 
 import android.graphics.Matrix;
@@ -35,7 +38,7 @@
 import java.util.ArrayList;
 
 public class AppWindowAnimator {
-    static final String TAG = "AppWindowAnimator";
+    static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowAnimator" : TAG_WM;
 
     private static final int PROLONG_ANIMATION_DISABLED = 0;
     static final int PROLONG_ANIMATION_AT_END = 1;
@@ -410,8 +413,7 @@
         final int NW = mAllAppWinAnimators.size();
         for (int i=0; i<NW; i++) {
             WindowStateAnimator winAnimator = mAllAppWinAnimators.get(i);
-            if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
-                    "performing show on: " + winAnimator);
+            if (DEBUG_VISIBILITY) Slog.v(TAG, "performing show on: " + winAnimator);
             winAnimator.performShowLocked();
             isAnimating |= winAnimator.isAnimating();
         }
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 3d00e02..fd5c704 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -17,9 +17,12 @@
 package com.android.server.wm;
 
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-import static com.android.server.wm.WindowManagerService.DEBUG_ANIM;
-import static com.android.server.wm.WindowManagerService.DEBUG_APP_TRANSITIONS;
-import static com.android.server.wm.WindowManagerService.TAG;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 import com.android.server.input.InputApplicationHandle;
 import com.android.server.wm.WindowManagerService.H;
@@ -44,6 +47,8 @@
  * really activity) that is displaying windows.
  */
 class AppWindowToken extends WindowToken {
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowToken" : TAG_WM;
+
     // Non-null only for application tokens.
     final IApplicationToken appToken;
 
@@ -54,10 +59,6 @@
 
     final boolean voiceInteraction;
 
-    // Whether the window has a saved surface from last pause, which can be
-    // used to start an entering animation earlier.
-    boolean mHasSavedSurface;
-
     // Whether we're performing an entering animation with a saved surface.
     boolean mAnimatingWithSavedSurface;
 
@@ -156,7 +157,7 @@
                 continue;
             }
             try {
-                if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG,
+                if (DEBUG_VISIBILITY) Slog.v(TAG,
                         "Setting visibility of " + win + ": " + (!clientHidden));
                 win.mClient.dispatchAppVisibility(!clientHidden);
             } catch (RemoteException e) {
@@ -174,7 +175,7 @@
         int numDrawn = 0;
         boolean nowGone = true;
 
-        if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG,
+        if (DEBUG_VISIBILITY) Slog.v(TAG,
                 "Update reported visibility: " + this);
         final int N = allAppWindows.size();
         for (int i=0; i<N; i++) {
@@ -185,12 +186,12 @@
                     || win.mDestroying) {
                 continue;
             }
-            if (WindowManagerService.DEBUG_VISIBILITY) {
-                Slog.v(WindowManagerService.TAG, "Win " + win + ": isDrawn="
+            if (DEBUG_VISIBILITY) {
+                Slog.v(TAG, "Win " + win + ": isDrawn="
                         + win.isDrawnLw()
                         + ", isAnimating=" + win.mWinAnimator.isAnimating());
                 if (!win.isDrawnLw()) {
-                    Slog.v(WindowManagerService.TAG, "Not displayed: s=" +
+                    Slog.v(TAG, "Not displayed: s=" +
                             win.mWinAnimator.mSurfaceController
                             + " pv=" + win.mPolicyVisibility
                             + " mDrawState=" + win.mWinAnimator.mDrawState
@@ -224,7 +225,7 @@
                 nowVisible = reportedVisible;
             }
         }
-        if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "VIS " + this + ": interesting="
+        if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
                 + numInteresting + " visible=" + numVisible);
         if (nowDrawn != reportedDrawn) {
             if (nowDrawn) {
@@ -235,8 +236,8 @@
             reportedDrawn = nowDrawn;
         }
         if (nowVisible != reportedVisible) {
-            if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(
-                    WindowManagerService.TAG, "Visibility changed in " + this
+            if (DEBUG_VISIBILITY) Slog.v(
+                    TAG, "Visibility changed in " + this
                     + ": vis=" + nowVisible);
             reportedVisible = nowVisible;
             Message m = service.mH.obtainMessage(
@@ -299,7 +300,7 @@
         final Task task = mTask;
         if (task != null) {
             if (!task.removeAppToken(this)) {
-                Slog.e(WindowManagerService.TAG, "removeAppFromTaskLocked: token=" + this
+                Slog.e(TAG, "removeAppFromTaskLocked: token=" + this
                         + " not found.");
             }
             task.mStack.mExitingAppTokens.remove(this);
@@ -316,39 +317,38 @@
         // currently animating with save surfaces. (If the app didn't even finish
         // drawing when the user exits, but we have a saved surface from last time,
         // we still want to keep that surface.)
-        mHasSavedSurface = allDrawn || mAnimatingWithSavedSurface;
-        if (mHasSavedSurface) {
-            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
-                    "Saving surface: " + this);
-            return true;
+        return allDrawn || mAnimatingWithSavedSurface;
+    }
+
+    boolean hasSavedSurface() {
+        for (int i = windows.size() -1; i >= 0; i--) {
+            final WindowState ws = windows.get(i);
+            if (ws.hasSavedSurface()) {
+                return true;
+            }
         }
         return false;
     }
 
     void restoreSavedSurfaces() {
-        if (!mHasSavedSurface) {
+        if (!hasSavedSurface()) {
             return;
         }
 
-        if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
+        if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG_WM,
                 "Restoring saved surfaces: " + this + ", allDrawn=" + allDrawn);
 
-        mHasSavedSurface = false;
         mAnimatingWithSavedSurface = true;
         for (int i = windows.size() - 1; i >= 0; i--) {
             WindowState ws = windows.get(i);
-            ws.mWinAnimator.mDrawState = WindowStateAnimator.READY_TO_SHOW;
+            ws.restoreSavedSurface();
         }
     }
 
     void destroySavedSurfaces() {
-        if (mHasSavedSurface) {
-            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
-                    "Destroying saved surface: " + this);
-            for (int i = windows.size() - 1; i >= 0; i--) {
-                final WindowState win = windows.get(i);
-                win.mWinAnimator.destroySurfaceLocked();
-            }
+        for (int i = windows.size() - 1; i >= 0; i--) {
+            WindowState win = windows.get(i);
+            win.destroySavedSurface();
         }
     }
 
@@ -362,8 +362,8 @@
                 // and never beyond allAppWindows bounds.
                 winNdx = Math.min(winNdx - 1, allAppWindows.size() - 1)) {
             WindowState win = allAppWindows.get(winNdx);
-            if (WindowManagerService.DEBUG_WINDOW_MOVEMENT) {
-                Slog.w(WindowManagerService.TAG, "removeAllWindows: removing win=" + win);
+            if (DEBUG_WINDOW_MOVEMENT) {
+                Slog.w(TAG, "removeAllWindows: removing win=" + win);
             }
 
             service.removeWindowLocked(win);
@@ -382,8 +382,8 @@
                 winNdx = Math.min(winNdx - 1, allAppWindows.size() - 1)) {
             WindowState win = allAppWindows.get(winNdx);
             if (win.mAppDied) {
-                if (WindowManagerService.DEBUG_WINDOW_MOVEMENT) {
-                    Slog.w(WindowManagerService.TAG, "removeAllDeadWindows: " + win);
+                if (DEBUG_WINDOW_MOVEMENT) {
+                    Slog.w(TAG, "removeAllDeadWindows: " + win);
                 }
                 // Set mDestroying, we don't want any animation or delayed removal here.
                 win.mDestroying = true;
diff --git a/services/core/java/com/android/server/wm/BlackFrame.java b/services/core/java/com/android/server/wm/BlackFrame.java
index 7b08354..5c29a0a 100644
--- a/services/core/java/com/android/server/wm/BlackFrame.java
+++ b/services/core/java/com/android/server/wm/BlackFrame.java
@@ -16,6 +16,13 @@
 
 package com.android.server.wm;
 
+import static android.graphics.PixelFormat.OPAQUE;
+import static android.view.SurfaceControl.FX_SURFACE_DIM;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
 import java.io.PrintWriter;
 
 import android.graphics.Matrix;
@@ -44,21 +51,20 @@
             int w = r-l;
             int h = b-t;
 
-            if (WindowManagerService.DEBUG_SURFACE_TRACE) {
+            if (DEBUG_SURFACE_TRACE) {
                 surface = new WindowSurfaceController.SurfaceTrace(session, "BlackSurface("
                         + l + ", " + t + ")",
-                        w, h, PixelFormat.OPAQUE, SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN);
+                        w, h, OPAQUE, FX_SURFACE_DIM | SurfaceControl.HIDDEN);
             } else {
                 surface = new SurfaceControl(session, "BlackSurface",
-                        w, h, PixelFormat.OPAQUE, SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN);
+                        w, h, OPAQUE, FX_SURFACE_DIM | SurfaceControl.HIDDEN);
             }
 
             surface.setAlpha(1);
             surface.setLayerStack(layerStack);
             surface.setLayer(layer);
             surface.show();
-            if (WindowManagerService.SHOW_TRANSACTIONS ||
-                    WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
+            if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG_WM,
                             "  BLACK " + surface + ": CREATE layer=" + layer);
         }
 
@@ -76,7 +82,7 @@
                     mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
                     mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
             if (false) {
-                Slog.i(WindowManagerService.TAG, "Black Surface @ (" + left + "," + top + "): ("
+                Slog.i(TAG_WM, "Black Surface @ (" + left + "," + top + "): ("
                         + mTmpFloats[Matrix.MTRANS_X] + ","
                         + mTmpFloats[Matrix.MTRANS_Y] + ") matrix=["
                         + mTmpFloats[Matrix.MSCALE_X] + ","
@@ -149,10 +155,8 @@
         if (mBlackSurfaces != null) {
             for (int i=0; i<mBlackSurfaces.length; i++) {
                 if (mBlackSurfaces[i] != null) {
-                    if (WindowManagerService.SHOW_TRANSACTIONS ||
-                            WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(
-                                    WindowManagerService.TAG,
-                                    "  BLACK " + mBlackSurfaces[i].surface + ": DESTROY");
+                    if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG_WM,
+                            "  BLACK " + mBlackSurfaces[i].surface + ": DESTROY");
                     mBlackSurfaces[i].surface.destroy();
                     mBlackSurfaces[i] = null;
                 }
diff --git a/services/core/java/com/android/server/wm/CircularDisplayMask.java b/services/core/java/com/android/server/wm/CircularDisplayMask.java
index 33cec64..ae41541 100644
--- a/services/core/java/com/android/server/wm/CircularDisplayMask.java
+++ b/services/core/java/com/android/server/wm/CircularDisplayMask.java
@@ -17,6 +17,9 @@
 package com.android.server.wm;
 
 
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -26,15 +29,15 @@
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
+import android.util.Slog;
 import android.view.Display;
 import android.view.Surface;
 import android.view.Surface.OutOfResourcesException;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
-import android.util.Slog;
 
 class CircularDisplayMask {
-    private static final String TAG = "CircularDisplayMask";
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "CircularDisplayMask" : TAG_WM;
 
     // size of the chin
     private int mScreenOffset = 0;
@@ -64,7 +67,7 @@
 
         SurfaceControl ctrl = null;
         try {
-            if (WindowManagerService.DEBUG_SURFACE_TRACE) {
+            if (DEBUG_SURFACE_TRACE) {
                 ctrl = new WindowSurfaceController.SurfaceTrace(session, "CircularDisplayMask",
                         mScreenSize.x, mScreenSize.y, PixelFormat.TRANSLUCENT,
                         SurfaceControl.HIDDEN);
diff --git a/services/core/java/com/android/server/wm/DimLayer.java b/services/core/java/com/android/server/wm/DimLayer.java
index 4b3620f..6657a7b 100644
--- a/services/core/java/com/android/server/wm/DimLayer.java
+++ b/services/core/java/com/android/server/wm/DimLayer.java
@@ -16,6 +16,12 @@
 
 package com.android.server.wm;
 
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.os.SystemClock;
@@ -26,7 +32,7 @@
 import java.io.PrintWriter;
 
 public class DimLayer {
-    private static final String TAG = "DimLayer";
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "DimLayer" : TAG_WM;
     private static final boolean DEBUG = false;
 
     public static final float RESIZING_HINT_ALPHA = 0.5f;
@@ -81,7 +87,7 @@
         if (DEBUG) Slog.v(TAG, "Ctor: displayId=" + displayId);
         SurfaceControl.openTransaction();
         try {
-            if (WindowManagerService.DEBUG_SURFACE_TRACE) {
+            if (DEBUG_SURFACE_TRACE) {
                 mDimSurface = new WindowSurfaceController.SurfaceTrace(service.mFxSession,
                     "DimSurface",
                     16, 16, PixelFormat.OPAQUE,
@@ -91,12 +97,11 @@
                     16, 16, PixelFormat.OPAQUE,
                     SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN);
             }
-            if (WindowManagerService.SHOW_TRANSACTIONS ||
-                    WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(TAG,
-                            "  DIM " + mDimSurface + ": CREATE");
+            if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG,
+                    "  DIM " + mDimSurface + ": CREATE");
             mDimSurface.setLayerStack(displayId);
         } catch (Exception e) {
-            Slog.e(WindowManagerService.TAG, "Exception creating Dim surface", e);
+            Slog.e(TAG_WM, "Exception creating Dim surface", e);
         } finally {
             SurfaceControl.closeTransaction();
         }
diff --git a/services/core/java/com/android/server/wm/DimLayerController.java b/services/core/java/com/android/server/wm/DimLayerController.java
index bd30bd5..6d1cec4 100644
--- a/services/core/java/com/android/server/wm/DimLayerController.java
+++ b/services/core/java/com/android/server/wm/DimLayerController.java
@@ -1,6 +1,8 @@
 package com.android.server.wm;
 
-import static com.android.server.wm.WindowManagerService.DEBUG_DIM_LAYER;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DIM_LAYER;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.LAYER_OFFSET_DIM;
 
 import android.graphics.Rect;
@@ -16,7 +18,7 @@
  * as well as other use cases (such as dimming above a dead window).
  */
 class DimLayerController {
-    private static final String TAG = "DimLayerController";
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "DimLayerController" : TAG_WM;
 
     /** Amount of time in milliseconds to animate the dim surface from one value to another,
      * when no window animation is driving it. */
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 898a9a4..9b64481 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -19,8 +19,8 @@
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
-import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
-import static com.android.server.wm.WindowManagerService.TAG;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
 
 import android.app.ActivityManager.StackId;
@@ -180,7 +180,7 @@
 
     TaskStack getHomeStack() {
         if (mHomeStack == null && mDisplayId == Display.DEFAULT_DISPLAY) {
-            Slog.e(TAG, "getHomeStack: Returning null from this=" + this);
+            Slog.e(TAG_WM, "getHomeStack: Returning null from this=" + this);
         }
         return mHomeStack;
     }
@@ -239,12 +239,12 @@
     void moveStack(TaskStack stack, boolean toTop) {
         if (StackId.isAlwaysOnTop(stack.mStackId) && !toTop) {
             // This stack is always-on-top silly...
-            Slog.w(TAG, "Ignoring move of always-on-top stack=" + stack + " to bottom");
+            Slog.w(TAG_WM, "Ignoring move of always-on-top stack=" + stack + " to bottom");
             return;
         }
 
         if (!mStacks.remove(stack)) {
-            Slog.wtf(TAG, "moving stack that was not added: " + stack, new Throwable());
+            Slog.wtf(TAG_WM, "moving stack that was not added: " + stack, new Throwable());
         }
 
         int addIndex = toTop ? mStacks.size() : 0;
@@ -422,7 +422,7 @@
         for (int i = 0; i < windows.size(); i++) {
             final WindowState win = windows.get(i);
             if (win.isHiddenFromUserLocked()) {
-                if (DEBUG_VISIBILITY) Slog.w(TAG, "user changing, hiding " + win
+                if (DEBUG_VISIBILITY) Slog.w(TAG_WM, "user changing, hiding " + win
                         + ", attrs=" + win.mAttrs.type + ", belonging to " + win.mOwnerUid);
                 win.hideLw(false);
             }
diff --git a/services/core/java/com/android/server/wm/DisplaySettings.java b/services/core/java/com/android/server/wm/DisplaySettings.java
index 80526f2..7f79686 100644
--- a/services/core/java/com/android/server/wm/DisplaySettings.java
+++ b/services/core/java/com/android/server/wm/DisplaySettings.java
@@ -16,16 +16,17 @@
 
 package com.android.server.wm;
 
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
 import android.graphics.Rect;
 import android.os.Environment;
 import android.util.AtomicFile;
 import android.util.Slog;
 import android.util.Xml;
+
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.XmlUtils;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -35,11 +36,15 @@
 import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
 /**
  * Current persistent settings about a display
  */
 public class DisplaySettings {
-    private static final String TAG = WindowManagerService.TAG;
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplaySettings" : TAG_WM;
 
     private final AtomicFile mFile;
     private final HashMap<String, Entry> mEntries = new HashMap<String, Entry>();
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 32c9b2a..8f3d3e3 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -27,13 +27,15 @@
 import static android.view.WindowManager.DOCKED_LEFT;
 import static android.view.WindowManager.DOCKED_RIGHT;
 import static android.view.WindowManager.DOCKED_TOP;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 /**
  * Keeps information about the docked stack divider.
  */
 public class DockedStackDividerController {
 
-    private static final String TAG = "DockedStackDividerController";
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "DockedStackDividerController" : TAG_WM;
 
     private final DisplayContent mDisplayContent;
     private final int mDividerWindowWidth;
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 0ef0e58..da89481 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -16,22 +16,15 @@
 
 package com.android.server.wm;
 
-import android.graphics.Matrix;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.view.animation.AnimationSet;
-import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
-import android.view.animation.ScaleAnimation;
-import android.view.animation.Transformation;
-import android.view.animation.TranslateAnimation;
-import com.android.server.input.InputApplicationHandle;
-import com.android.server.input.InputWindowHandle;
-import com.android.server.wm.WindowManagerService.DragInputEventReceiver;
-import com.android.server.wm.WindowManagerService.H;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 import android.content.ClipData;
 import android.content.ClipDescription;
+import android.graphics.Matrix;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.Region;
@@ -47,6 +40,19 @@
 import android.view.SurfaceControl;
 import android.view.View;
 import android.view.WindowManager;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.view.animation.AnimationSet;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+import android.view.animation.ScaleAnimation;
+import android.view.animation.Transformation;
+import android.view.animation.TranslateAnimation;
+
+import com.android.server.input.InputApplicationHandle;
+import com.android.server.input.InputWindowHandle;
+import com.android.server.wm.WindowManagerService.DragInputEventReceiver;
+import com.android.server.wm.WindowManagerService.H;
 
 import java.util.ArrayList;
 
@@ -114,9 +120,9 @@
      */
     void register(Display display) {
         mDisplay = display;
-        if (WindowManagerService.DEBUG_DRAG) Slog.d(WindowManagerService.TAG, "registering drag input channel");
+        if (DEBUG_DRAG) Slog.d(TAG_WM, "registering drag input channel");
         if (mClientChannel != null) {
-            Slog.e(WindowManagerService.TAG, "Duplicate register of drag input channel");
+            Slog.e(TAG_WM, "Duplicate register of drag input channel");
         } else {
             InputChannel[] channels = InputChannel.openInputChannelPair("drag");
             mServerChannel = channels[0];
@@ -161,17 +167,17 @@
             mDragWindowHandle.frameBottom = p.y;
 
             // Pause rotations before a drag.
-            if (WindowManagerService.DEBUG_ORIENTATION) {
-                Slog.d(WindowManagerService.TAG, "Pausing rotation during drag");
+            if (DEBUG_ORIENTATION) {
+                Slog.d(TAG_WM, "Pausing rotation during drag");
             }
             mService.pauseRotationLocked();
         }
     }
 
     void unregister() {
-        if (WindowManagerService.DEBUG_DRAG) Slog.d(WindowManagerService.TAG, "unregistering drag input channel");
+        if (DEBUG_DRAG) Slog.d(TAG_WM, "unregistering drag input channel");
         if (mClientChannel == null) {
-            Slog.e(WindowManagerService.TAG, "Unregister of nonexistent drag input channel");
+            Slog.e(TAG_WM, "Unregister of nonexistent drag input channel");
         } else {
             mService.mInputManager.unregisterInputChannel(mServerChannel);
             mInputEventReceiver.dispose();
@@ -185,8 +191,8 @@
             mDragApplicationHandle = null;
 
             // Resume rotations after a drag.
-            if (WindowManagerService.DEBUG_ORIENTATION) {
-                Slog.d(WindowManagerService.TAG, "Resuming rotation after drag");
+            if (DEBUG_ORIENTATION) {
+                Slog.d(TAG_WM, "Resuming rotation after drag");
             }
             mService.resumeRotationLocked();
         }
@@ -210,8 +216,8 @@
         mNotifiedWindows.clear();
         mDragInProgress = true;
 
-        if (WindowManagerService.DEBUG_DRAG) {
-            Slog.d(WindowManagerService.TAG, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")");
+        if (DEBUG_DRAG) {
+            Slog.d(TAG_WM, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")");
         }
 
         final WindowList windows = mService.getWindowListLocked(mDisplay);
@@ -238,8 +244,8 @@
         if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
             final IBinder winBinder = newWin.mClient.asBinder();
             if (winBinder != mLocalWin) {
-                if (WindowManagerService.DEBUG_DRAG) {
-                    Slog.d(WindowManagerService.TAG, "Not dispatching local DRAG_STARTED to " + newWin);
+                if (DEBUG_DRAG) {
+                    Slog.d(TAG_WM, "Not dispatching local DRAG_STARTED to " + newWin);
                 }
                 return;
             }
@@ -253,7 +259,7 @@
                 // track each window that we've notified that the drag is starting
                 mNotifiedWindows.add(newWin);
             } catch (RemoteException e) {
-                Slog.w(WindowManagerService.TAG, "Unable to drag-start window " + newWin);
+                Slog.w(TAG_WM, "Unable to drag-start window " + newWin);
             } finally {
                 // if the callee was local, the dispatch has already recycled the event
                 if (Process.myPid() != newWin.mSession.mPid) {
@@ -275,8 +281,8 @@
                     return;
                 }
             }
-            if (WindowManagerService.DEBUG_DRAG) {
-                Slog.d(WindowManagerService.TAG, "need to send DRAG_STARTED to new window " + newWin);
+            if (DEBUG_DRAG) {
+                Slog.d(TAG_WM, "need to send DRAG_STARTED to new window " + newWin);
             }
             sendDragStartedLw(newWin, mCurrentX, mCurrentY, mDataDescription);
         }
@@ -285,8 +291,8 @@
     private void broadcastDragEndedLw() {
         final int myPid = Process.myPid();
 
-        if (WindowManagerService.DEBUG_DRAG) {
-            Slog.d(WindowManagerService.TAG, "broadcasting DRAG_ENDED");
+        if (DEBUG_DRAG) {
+            Slog.d(TAG_WM, "broadcasting DRAG_ENDED");
         }
         for (WindowState ws : mNotifiedWindows) {
             float x = 0;
@@ -301,7 +307,7 @@
             try {
                 ws.mClient.dispatchDragEvent(evt);
             } catch (RemoteException e) {
-                Slog.w(WindowManagerService.TAG, "Unable to drag-end window " + ws);
+                Slog.w(TAG_WM, "Unable to drag-end window " + ws);
             }
             // if the current window is in the same process,
             // the dispatch has already recycled the event
@@ -356,24 +362,24 @@
         final int myPid = Process.myPid();
 
         // Move the surface to the given touch
-        if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(
-                WindowManagerService.TAG, ">>> OPEN TRANSACTION notifyMoveLw");
+        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(
+                TAG_WM, ">>> OPEN TRANSACTION notifyMoveLw");
         SurfaceControl.openTransaction();
         try {
             mSurfaceControl.setPosition(x - mThumbOffsetX, y - mThumbOffsetY);
-            if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "  DRAG "
+            if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, "  DRAG "
                     + mSurfaceControl + ": pos=(" +
                     (int)(x - mThumbOffsetX) + "," + (int)(y - mThumbOffsetY) + ")");
         } finally {
             SurfaceControl.closeTransaction();
-            if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(
-                    WindowManagerService.TAG, "<<< CLOSE TRANSACTION notifyMoveLw");
+            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(
+                    TAG_WM, "<<< CLOSE TRANSACTION notifyMoveLw");
         }
 
         // Tell the affected window
         WindowState touchedWin = getTouchedWinAtPointLw(x, y);
         if (touchedWin == null) {
-            if (WindowManagerService.DEBUG_DRAG) Slog.d(WindowManagerService.TAG, "No touched win at x=" + x + " y=" + y);
+            if (DEBUG_DRAG) Slog.d(TAG_WM, "No touched win at x=" + x + " y=" + y);
             return;
         }
         if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
@@ -387,8 +393,8 @@
         try {
             // have we dragged over a new window?
             if ((touchedWin != mTargetWindow) && (mTargetWindow != null)) {
-                if (WindowManagerService.DEBUG_DRAG) {
-                    Slog.d(WindowManagerService.TAG, "sending DRAG_EXITED to " + mTargetWindow);
+                if (DEBUG_DRAG) {
+                    Slog.d(TAG_WM, "sending DRAG_EXITED to " + mTargetWindow);
                 }
                 // force DRAG_EXITED_EVENT if appropriate
                 DragEvent evt = obtainDragEvent(mTargetWindow, DragEvent.ACTION_DRAG_EXITED,
@@ -399,8 +405,8 @@
                 }
             }
             if (touchedWin != null) {
-                if (false && WindowManagerService.DEBUG_DRAG) {
-                    Slog.d(WindowManagerService.TAG, "sending DRAG_LOCATION to " + touchedWin);
+                if (false && DEBUG_DRAG) {
+                    Slog.d(TAG_WM, "sending DRAG_LOCATION to " + touchedWin);
                 }
                 DragEvent evt = obtainDragEvent(touchedWin, DragEvent.ACTION_DRAG_LOCATION,
                         x, y, null, null, null, null, false);
@@ -410,7 +416,7 @@
                 }
             }
         } catch (RemoteException e) {
-            Slog.w(WindowManagerService.TAG, "can't send drag notification to windows");
+            Slog.w(TAG_WM, "can't send drag notification to windows");
         }
         mTargetWindow = touchedWin;
     }
@@ -437,8 +443,8 @@
             return true;
         }
 
-        if (WindowManagerService.DEBUG_DRAG) {
-            Slog.d(WindowManagerService.TAG, "sending DROP to " + touchedWin);
+        if (DEBUG_DRAG) {
+            Slog.d(TAG_WM, "sending DROP to " + touchedWin);
         }
         final int myPid = Process.myPid();
         final IBinder token = touchedWin.mClient.asBinder();
@@ -452,7 +458,7 @@
             Message msg = mService.mH.obtainMessage(H.DRAG_END_TIMEOUT, token);
             mService.mH.sendMessageDelayed(msg, 5000);
         } catch (RemoteException e) {
-            Slog.w(WindowManagerService.TAG, "can't send drop notification to win " + touchedWin);
+            Slog.w(TAG_WM, "can't send drop notification to win " + touchedWin);
             return true;
         } finally {
             if (myPid != touchedWin.mSession.mPid) {
@@ -566,4 +572,4 @@
         set.start();  // Will start on the first call to getTransformation.
         return set;
     }
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java
index 0a372d8..3186d3d 100644
--- a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java
+++ b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java
@@ -17,6 +17,10 @@
 package com.android.server.wm;
 
 
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -32,7 +36,7 @@
 import android.view.SurfaceSession;
 
 class EmulatorDisplayOverlay {
-    private static final String TAG = "EmulatorDisplayOverlay";
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "EmulatorDisplayOverlay" : TAG_WM;
 
     // Display dimensions
     private Point mScreenSize;
@@ -53,7 +57,7 @@
 
         SurfaceControl ctrl = null;
         try {
-            if (WindowManagerService.DEBUG_SURFACE_TRACE) {
+            if (DEBUG_SURFACE_TRACE) {
                 ctrl = new WindowSurfaceController.SurfaceTrace(session, "EmulatorDisplayOverlay",
                         mScreenSize.x, mScreenSize.y, PixelFormat.TRANSLUCENT,
                         SurfaceControl.HIDDEN);
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 5511136..e42658e 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -16,9 +16,11 @@
 
 package com.android.server.wm;
 
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
-import static com.android.server.wm.WindowManagerService.DEBUG_FOCUS_LIGHT;
-import static com.android.server.wm.WindowManagerService.DEBUG_INPUT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 import android.app.ActivityManagerNative;
 import android.graphics.Rect;
@@ -79,7 +81,7 @@
         synchronized (mService.mWindowMap) {
             WindowState windowState = (WindowState) inputWindowHandle.windowState;
             if (windowState != null) {
-                Slog.i(WindowManagerService.TAG, "WINDOW DIED " + windowState);
+                Slog.i(TAG_WM, "WINDOW DIED " + windowState);
                 mService.removeWindowLocked(windowState);
             }
         }
@@ -108,7 +110,7 @@
             }
 
             if (windowState != null) {
-                Slog.i(WindowManagerService.TAG, "Input event dispatching timed out "
+                Slog.i(TAG_WM, "Input event dispatching timed out "
                         + "sending to " + windowState.mAttrs.getTitle()
                         + ".  Reason: " + reason);
                 // Figure out whether this window is layered above system windows.
@@ -118,11 +120,11 @@
                         WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
                 aboveSystem = windowState.mBaseLayer > systemAlertLayer;
             } else if (appWindowToken != null) {
-                Slog.i(WindowManagerService.TAG, "Input event dispatching timed out "
+                Slog.i(TAG_WM, "Input event dispatching timed out "
                         + "sending to application " + appWindowToken.stringName
                         + ".  Reason: " + reason);
             } else {
-                Slog.i(WindowManagerService.TAG, "Input event dispatching timed out "
+                Slog.i(TAG_WM, "Input event dispatching timed out "
                         + ".  Reason: " + reason);
             }
 
@@ -212,7 +214,7 @@
         }
 
         if (DEBUG_INPUT) {
-            Slog.d(WindowManagerService.TAG, "addInputWindowHandle: "
+            Slog.d(TAG_WM, "addInputWindowHandle: "
                     + child + ", " + inputWindowHandle);
         }
         addInputWindowHandleLw(inputWindowHandle);
@@ -235,7 +237,7 @@
         }
         mUpdateInputWindowsNeeded = false;
 
-        if (false) Slog.d(WindowManagerService.TAG, ">>>>>> ENTERED updateInputWindowsLw");
+        if (false) Slog.d(TAG_WM, ">>>>>> ENTERED updateInputWindowsLw");
 
         // Populate the input window list with information about all of the windows that
         // could potentially receive input.
@@ -247,28 +249,28 @@
         // If there's a drag in flight, provide a pseudowindow to catch drag input
         final boolean inDrag = (mService.mDragState != null);
         if (inDrag) {
-            if (WindowManagerService.DEBUG_DRAG) {
-                Log.d(WindowManagerService.TAG, "Inserting drag window");
+            if (DEBUG_DRAG) {
+                Log.d(TAG_WM, "Inserting drag window");
             }
             final InputWindowHandle dragWindowHandle = mService.mDragState.mDragWindowHandle;
             if (dragWindowHandle != null) {
                 addInputWindowHandleLw(dragWindowHandle);
             } else {
-                Slog.w(WindowManagerService.TAG, "Drag is in progress but there is no "
+                Slog.w(TAG_WM, "Drag is in progress but there is no "
                         + "drag window handle.");
             }
         }
 
         final boolean inPositioning = (mService.mTaskPositioner != null);
         if (inPositioning) {
-            if (WindowManagerService.DEBUG_TASK_POSITIONING) {
-                Log.d(WindowManagerService.TAG, "Inserting window handle for repositioning");
+            if (DEBUG_TASK_POSITIONING) {
+                Log.d(TAG_WM, "Inserting window handle for repositioning");
             }
             final InputWindowHandle dragWindowHandle = mService.mTaskPositioner.mDragWindowHandle;
             if (dragWindowHandle != null) {
                 addInputWindowHandleLw(dragWindowHandle);
             } else {
-                Slog.e(WindowManagerService.TAG,
+                Slog.e(TAG_WM,
                         "Repositioning is in progress but there is no drag window handle.");
             }
         }
@@ -328,7 +330,7 @@
         // Clear the list in preparation for the next round.
         clearInputWindowHandlesLw();
 
-        if (false) Slog.d(WindowManagerService.TAG, "<<<<<<< EXITED updateInputWindowsLw");
+        if (false) Slog.d(TAG_WM, "<<<<<<< EXITED updateInputWindowsLw");
     }
 
     /* Notifies that the input device configuration has changed. */
@@ -416,7 +418,7 @@
      */
     public void setInputFocusLw(WindowState newWindow, boolean updateInputWindows) {
         if (DEBUG_FOCUS_LIGHT || DEBUG_INPUT) {
-            Slog.d(WindowManagerService.TAG, "Input focus has changed to " + newWindow);
+            Slog.d(TAG_WM, "Input focus has changed to " + newWindow);
         }
 
         if (newWindow != mInputFocus) {
@@ -452,7 +454,7 @@
     public void pauseDispatchingLw(WindowToken window) {
         if (! window.paused) {
             if (DEBUG_INPUT) {
-                Slog.v(WindowManagerService.TAG, "Pausing WindowToken " + window);
+                Slog.v(TAG_WM, "Pausing WindowToken " + window);
             }
 
             window.paused = true;
@@ -463,7 +465,7 @@
     public void resumeDispatchingLw(WindowToken window) {
         if (window.paused) {
             if (DEBUG_INPUT) {
-                Slog.v(WindowManagerService.TAG, "Resuming WindowToken " + window);
+                Slog.v(TAG_WM, "Resuming WindowToken " + window);
             }
 
             window.paused = false;
@@ -474,7 +476,7 @@
     public void freezeInputDispatchingLw() {
         if (! mInputDispatchFrozen) {
             if (DEBUG_INPUT) {
-                Slog.v(WindowManagerService.TAG, "Freezing input dispatching");
+                Slog.v(TAG_WM, "Freezing input dispatching");
             }
 
             mInputDispatchFrozen = true;
@@ -485,7 +487,7 @@
     public void thawInputDispatchingLw() {
         if (mInputDispatchFrozen) {
             if (DEBUG_INPUT) {
-                Slog.v(WindowManagerService.TAG, "Thawing input dispatching");
+                Slog.v(TAG_WM, "Thawing input dispatching");
             }
 
             mInputDispatchFrozen = false;
@@ -496,7 +498,7 @@
     public void setEventDispatchingLw(boolean enabled) {
         if (mInputDispatchEnabled != enabled) {
             if (DEBUG_INPUT) {
-                Slog.v(WindowManagerService.TAG, "Setting event dispatching to " + enabled);
+                Slog.v(TAG_WM, "Setting event dispatching to " + enabled);
             }
 
             mInputDispatchEnabled = enabled;
diff --git a/services/core/java/com/android/server/wm/KeyguardDisableHandler.java b/services/core/java/com/android/server/wm/KeyguardDisableHandler.java
index 37d811f..377071d 100644
--- a/services/core/java/com/android/server/wm/KeyguardDisableHandler.java
+++ b/services/core/java/com/android/server/wm/KeyguardDisableHandler.java
@@ -16,6 +16,9 @@
 
 package com.android.server.wm;
 
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
 import android.app.ActivityManagerNative;
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
@@ -29,7 +32,7 @@
 import android.view.WindowManagerPolicy;
 
 public class KeyguardDisableHandler extends Handler {
-    private static final String TAG = "KeyguardDisableHandler";
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "KeyguardDisableHandler" : TAG_WM;
 
     private static final int ALLOW_DISABLE_YES = 1;
     private static final int ALLOW_DISABLE_NO = 0;
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index 3158c47..c118a21 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -16,11 +16,16 @@
 
 package com.android.server.wm;
 
-import java.io.PrintWriter;
-
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
-import static com.android.server.wm.WindowSurfaceController.SurfaceTrace;
 import static com.android.server.wm.WindowStateAnimator.WINDOW_FREEZE_LAYER;
+import static com.android.server.wm.WindowSurfaceController.SurfaceTrace;
+
 import android.content.Context;
 import android.graphics.Matrix;
 import android.graphics.PixelFormat;
@@ -28,16 +33,18 @@
 import android.util.Slog;
 import android.view.Display;
 import android.view.DisplayInfo;
-import android.view.Surface.OutOfResourcesException;
 import android.view.Surface;
+import android.view.Surface.OutOfResourcesException;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Transformation;
 
+import java.io.PrintWriter;
+
 class ScreenRotationAnimation {
-    static final String TAG = "ScreenRotationAnimation";
+    static final String TAG = TAG_WITH_CLASS_NAME ? "ScreenRotationAnimation" : TAG_WM;
     static final boolean DEBUG_STATE = false;
     static final boolean DEBUG_TRANSFORMS = false;
     static final boolean TWO_PHASE_ANIMATION = false;
@@ -244,7 +251,7 @@
         mOriginalHeight = originalHeight;
 
         if (!inTransaction) {
-            if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
+            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
                     ">>> OPEN TRANSACTION ScreenRotationAnimation");
             SurfaceControl.openTransaction();
         }
@@ -256,7 +263,7 @@
                     flags |= SurfaceControl.SECURE;
                 }
 
-                if (WindowManagerService.DEBUG_SURFACE_TRACE) {
+                if (DEBUG_SURFACE_TRACE) {
                     mSurfaceControl = new SurfaceTrace(session, "ScreenshotSurface",
                             mWidth, mHeight,
                             PixelFormat.OPAQUE, flags);
@@ -282,15 +289,14 @@
                 Slog.w(TAG, "Unable to allocate freeze surface", e);
             }
 
-            if (WindowManagerService.SHOW_TRANSACTIONS ||
-                    WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
-                            "  FREEZE " + mSurfaceControl + ": CREATE");
+            if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG_WM,
+                    "  FREEZE " + mSurfaceControl + ": CREATE");
 
             setRotationInTransaction(originalRotation);
         } finally {
             if (!inTransaction) {
                 SurfaceControl.closeTransaction();
-                if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
+                if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
                         "<<< CLOSE TRANSACTION ScreenRotationAnimation");
             }
         }
@@ -537,8 +543,8 @@
 
         final int layerStack = mDisplayContent.getDisplay().getLayerStack();
         if (USE_CUSTOM_BLACK_FRAME && mCustomBlackFrame == null) {
-            if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
-                    WindowManagerService.TAG,
+            if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
+                    TAG_WM,
                     ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
             SurfaceControl.openTransaction();
 
@@ -561,15 +567,15 @@
                 Slog.w(TAG, "Unable to allocate black surface", e);
             } finally {
                 SurfaceControl.closeTransaction();
-                if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
-                        WindowManagerService.TAG,
+                if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
+                        TAG_WM,
                         "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
             }
         }
 
         if (!customAnim && mExitingBlackFrame == null) {
-            if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
-                    WindowManagerService.TAG,
+            if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
+                    TAG_WM,
                     ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
             SurfaceControl.openTransaction();
             try {
@@ -601,15 +607,15 @@
                 Slog.w(TAG, "Unable to allocate black surface", e);
             } finally {
                 SurfaceControl.closeTransaction();
-                if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
-                        WindowManagerService.TAG,
+                if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
+                        TAG_WM,
                         "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
             }
         }
 
         if (customAnim && mEnteringBlackFrame == null) {
-            if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
-                    WindowManagerService.TAG,
+            if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
+                    TAG_WM,
                     ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
             SurfaceControl.openTransaction();
 
@@ -623,8 +629,8 @@
                 Slog.w(TAG, "Unable to allocate black surface", e);
             } finally {
                 SurfaceControl.closeTransaction();
-                if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
-                        WindowManagerService.TAG,
+                if (SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
+                        TAG_WM,
                         "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation");
             }
         }
@@ -657,8 +663,8 @@
     public void kill() {
         if (DEBUG_STATE) Slog.v(TAG, "Kill!");
         if (mSurfaceControl != null) {
-            if (WindowManagerService.SHOW_TRANSACTIONS ||
-                    WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
+            if (SHOW_TRANSACTIONS ||
+                    SHOW_SURFACE_ALLOC) Slog.i(TAG_WM,
                             "  FREEZE " + mSurfaceControl + ": DESTROY");
             mSurfaceControl.destroy();
             mSurfaceControl = null;
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 6e2e830..1b6957d 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -16,12 +16,11 @@
 
 package com.android.server.wm;
 
-import android.view.IWindowId;
-import android.view.IWindowSessionCallback;
-import com.android.internal.view.IInputContext;
-import com.android.internal.view.IInputMethodClient;
-import com.android.internal.view.IInputMethodManager;
-import com.android.server.wm.WindowManagerService.H;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 import android.content.ClipData;
 import android.content.Context;
@@ -39,13 +38,20 @@
 import android.util.Slog;
 import android.view.Display;
 import android.view.IWindow;
+import android.view.IWindowId;
 import android.view.IWindowSession;
+import android.view.IWindowSessionCallback;
 import android.view.InputChannel;
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
 import android.view.WindowManager;
 
+import com.android.internal.view.IInputContext;
+import com.android.internal.view.IInputMethodClient;
+import com.android.internal.view.IInputMethodManager;
+import com.android.server.wm.WindowManagerService.H;
+
 import java.io.PrintWriter;
 
 /**
@@ -131,7 +137,7 @@
         } catch (RuntimeException e) {
             // Log all 'real' exceptions thrown to the caller
             if (!(e instanceof SecurityException)) {
-                Slog.wtf(WindowManagerService.TAG, "Window Session Crash", e);
+                Slog.wtf(TAG_WM, "Window Session Crash", e);
             }
             throw e;
         }
@@ -200,13 +206,13 @@
             Rect outVisibleInsets, Rect outStableInsets, Rect outsets, Configuration
                     outConfig,
             Surface outSurface) {
-        if (false) Slog.d(WindowManagerService.TAG, ">>>>>> ENTERED relayout from "
+        if (false) Slog.d(TAG_WM, ">>>>>> ENTERED relayout from "
                 + Binder.getCallingPid());
         int res = mService.relayoutWindow(this, window, seq, attrs,
                 requestedWidth, requestedHeight, viewFlags, flags,
                 outFrame, outOverscanInsets, outContentInsets, outVisibleInsets,
                 outStableInsets, outsets, outConfig, outSurface);
-        if (false) Slog.d(WindowManagerService.TAG, "<<<<<< EXITING relayout to "
+        if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to "
                 + Binder.getCallingPid());
         return res;
     }
@@ -235,7 +241,7 @@
 
     public void finishDrawing(IWindow window) {
         if (WindowManagerService.localLOGV) Slog.v(
-            WindowManagerService.TAG, "IWindow finishDrawing called for " + window);
+            TAG_WM, "IWindow finishDrawing called for " + window);
         mService.finishDrawingWindow(this, window);
     }
 
@@ -275,24 +281,24 @@
     public boolean performDrag(IWindow window, IBinder dragToken,
             float touchX, float touchY, float thumbCenterX, float thumbCenterY,
             ClipData data) {
-        if (WindowManagerService.DEBUG_DRAG) {
-            Slog.d(WindowManagerService.TAG, "perform drag: win=" + window + " data=" + data);
+        if (DEBUG_DRAG) {
+            Slog.d(TAG_WM, "perform drag: win=" + window + " data=" + data);
         }
 
         synchronized (mService.mWindowMap) {
             if (mService.mDragState == null) {
-                Slog.w(WindowManagerService.TAG, "No drag prepared");
+                Slog.w(TAG_WM, "No drag prepared");
                 throw new IllegalStateException("performDrag() without prepareDrag()");
             }
 
             if (dragToken != mService.mDragState.mToken) {
-                Slog.w(WindowManagerService.TAG, "Performing mismatched drag");
+                Slog.w(TAG_WM, "Performing mismatched drag");
                 throw new IllegalStateException("performDrag() does not match prepareDrag()");
             }
 
             WindowState callingWin = mService.windowForClientLocked(null, window, false);
             if (callingWin == null) {
-                Slog.w(WindowManagerService.TAG, "Bad requesting window " + window);
+                Slog.w(TAG_WM, "Bad requesting window " + window);
                 return false;  // !!! TODO: throw here?
             }
 
@@ -317,7 +323,7 @@
             mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
             if (!mService.mInputManager.transferTouchFocus(callingWin.mInputChannel,
                     mService.mDragState.mServerChannel)) {
-                Slog.e(WindowManagerService.TAG, "Unable to transfer touch focus");
+                Slog.e(TAG_WM, "Unable to transfer touch focus");
                 mService.mDragState.unregister();
                 mService.mDragState = null;
                 mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
@@ -333,8 +339,8 @@
 
             // Make the surface visible at the proper location
             final SurfaceControl surfaceControl = mService.mDragState.mSurfaceControl;
-            if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(
-                    WindowManagerService.TAG, ">>> OPEN TRANSACTION performDrag");
+            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(
+                    TAG_WM, ">>> OPEN TRANSACTION performDrag");
             SurfaceControl.openTransaction();
             try {
                 surfaceControl.setPosition(touchX - thumbCenterX,
@@ -344,8 +350,8 @@
                 surfaceControl.show();
             } finally {
                 SurfaceControl.closeTransaction();
-                if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(
-                        WindowManagerService.TAG, "<<< CLOSE TRANSACTION performDrag");
+                if (SHOW_LIGHT_TRANSACTIONS) Slog.i(
+                        TAG_WM, "<<< CLOSE TRANSACTION performDrag");
             }
         }
 
@@ -353,16 +359,16 @@
     }
 
     public boolean startMovingTask(IWindow window, float startX, float startY) {
-        if (WindowManagerService.DEBUG_TASK_POSITIONING) Slog.d(
-                WindowManagerService.TAG, "startMovingTask: {" + startX + "," + startY + "}");
+        if (DEBUG_TASK_POSITIONING) Slog.d(
+                TAG_WM, "startMovingTask: {" + startX + "," + startY + "}");
 
         return mService.startMovingTask(window, startX, startY);
     }
 
     public void reportDropResult(IWindow window, boolean consumed) {
         IBinder token = window.asBinder();
-        if (WindowManagerService.DEBUG_DRAG) {
-            Slog.d(WindowManagerService.TAG, "Drop result=" + consumed + " reported by " + token);
+        if (DEBUG_DRAG) {
+            Slog.d(TAG_WM, "Drop result=" + consumed + " reported by " + token);
         }
 
         synchronized (mService.mWindowMap) {
@@ -371,13 +377,13 @@
                 if (mService.mDragState == null) {
                     // Most likely the drop recipient ANRed and we ended the drag
                     // out from under it.  Log the issue and move on.
-                    Slog.w(WindowManagerService.TAG, "Drop result given but no drag in progress");
+                    Slog.w(TAG_WM, "Drop result given but no drag in progress");
                     return;
                 }
 
                 if (mService.mDragState.mToken != token) {
                     // We're in a drag, but the wrong window has responded.
-                    Slog.w(WindowManagerService.TAG, "Invalid drop-result claim by " + window);
+                    Slog.w(TAG_WM, "Invalid drop-result claim by " + window);
                     throw new IllegalStateException("reportDropResult() by non-recipient");
                 }
 
@@ -387,7 +393,7 @@
                 mService.mH.removeMessages(H.DRAG_END_TIMEOUT, window.asBinder());
                 WindowState callingWin = mService.windowForClientLocked(null, window, false);
                 if (callingWin == null) {
-                    Slog.w(WindowManagerService.TAG, "Bad result-reporting window " + window);
+                    Slog.w(TAG_WM, "Bad result-reporting window " + window);
                     return;  // !!! TODO: throw here?
                 }
 
@@ -400,20 +406,20 @@
     }
 
     public void cancelDragAndDrop(IBinder dragToken) {
-        if (WindowManagerService.DEBUG_DRAG) {
-            Slog.d(WindowManagerService.TAG, "cancelDragAndDrop");
+        if (DEBUG_DRAG) {
+            Slog.d(TAG_WM, "cancelDragAndDrop");
         }
 
         synchronized (mService.mWindowMap) {
             long ident = Binder.clearCallingIdentity();
             try {
                 if (mService.mDragState == null) {
-                    Slog.w(WindowManagerService.TAG, "cancelDragAndDrop() without prepareDrag()");
+                    Slog.w(TAG_WM, "cancelDragAndDrop() without prepareDrag()");
                     throw new IllegalStateException("cancelDragAndDrop() without prepareDrag()");
                 }
 
                 if (mService.mDragState.mToken != dragToken) {
-                    Slog.w(WindowManagerService.TAG,
+                    Slog.w(TAG_WM,
                             "cancelDragAndDrop() does not match prepareDrag()");
                     throw new IllegalStateException(
                             "cancelDragAndDrop() does not match prepareDrag()");
@@ -428,14 +434,14 @@
     }
 
     public void dragRecipientEntered(IWindow window) {
-        if (WindowManagerService.DEBUG_DRAG) {
-            Slog.d(WindowManagerService.TAG, "Drag into new candidate view @ " + window.asBinder());
+        if (DEBUG_DRAG) {
+            Slog.d(TAG_WM, "Drag into new candidate view @ " + window.asBinder());
         }
     }
 
     public void dragRecipientExited(IWindow window) {
-        if (WindowManagerService.DEBUG_DRAG) {
-            Slog.d(WindowManagerService.TAG, "Drag from old candidate view @ " + window.asBinder());
+        if (DEBUG_DRAG) {
+            Slog.d(TAG_WM, "Drag from old candidate view @ " + window.asBinder());
         }
     }
 
@@ -518,10 +524,10 @@
     void windowAddedLocked() {
         if (mSurfaceSession == null) {
             if (WindowManagerService.localLOGV) Slog.v(
-                WindowManagerService.TAG, "First window added to " + this + ", creating SurfaceSession");
+                TAG_WM, "First window added to " + this + ", creating SurfaceSession");
             mSurfaceSession = new SurfaceSession();
-            if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(
-                    WindowManagerService.TAG, "  NEW SURFACE SESSION " + mSurfaceSession);
+            if (SHOW_TRANSACTIONS) Slog.i(
+                    TAG_WM, "  NEW SURFACE SESSION " + mSurfaceSession);
             mService.mSessions.add(this);
             if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {
                 mService.dispatchNewAnimatorScaleLocked(this);
@@ -540,14 +546,14 @@
             mService.mSessions.remove(this);
             if (mSurfaceSession != null) {
                 if (WindowManagerService.localLOGV) Slog.v(
-                    WindowManagerService.TAG, "Last window removed from " + this
+                    TAG_WM, "Last window removed from " + this
                     + ", destroying " + mSurfaceSession);
-                if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(
-                        WindowManagerService.TAG, "  KILL SURFACE SESSION " + mSurfaceSession);
+                if (SHOW_TRANSACTIONS) Slog.i(
+                        TAG_WM, "  KILL SURFACE SESSION " + mSurfaceSession);
                 try {
                     mSurfaceSession.kill();
                 } catch (Exception e) {
-                    Slog.w(WindowManagerService.TAG, "Exception thrown when killing surface session "
+                    Slog.w(TAG_WM, "Exception thrown when killing surface session "
                         + mSurfaceSession + " in session " + this
                         + ": " + e.toString());
                 }
diff --git a/services/core/java/com/android/server/wm/StrictModeFlash.java b/services/core/java/com/android/server/wm/StrictModeFlash.java
index fb5876b..d1547eb 100644
--- a/services/core/java/com/android/server/wm/StrictModeFlash.java
+++ b/services/core/java/com/android/server/wm/StrictModeFlash.java
@@ -17,6 +17,9 @@
 package com.android.server.wm;
 
 
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.PixelFormat;
@@ -29,7 +32,7 @@
 import android.view.SurfaceSession;
 
 class StrictModeFlash {
-    private static final String TAG = "StrictModeFlash";
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "StrictModeFlash" : TAG_WM;
 
     private final SurfaceControl mSurfaceControl;
     private final Surface mSurface = new Surface();
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index e4f6c56..72a8343 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -19,12 +19,11 @@
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.app.ActivityManager.RESIZE_MODE_SYSTEM_SCREEN_ROTATION;
-import static com.android.server.wm.WindowManagerService.TAG;
-import static com.android.server.wm.WindowManagerService.DEBUG_RESIZE;
-import static com.android.server.wm.WindowManagerService.DEBUG_STACK;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
 import static com.android.server.wm.WindowManagerService.H.RESIZE_TASK;
 import static com.android.server.wm.WindowManagerService.H.SHOW_NON_RESIZEABLE_DOCK_TOAST;
 import static android.view.WindowManager.DOCKED_INVALID;
@@ -156,11 +155,11 @@
 
     void removeLocked() {
         if (!mAppTokens.isEmpty() && mStack.isAnimating()) {
-            if (DEBUG_STACK) Slog.i(TAG, "removeTask: deferring removing taskId=" + mTaskId);
+            if (DEBUG_STACK) Slog.i(TAG_WM, "removeTask: deferring removing taskId=" + mTaskId);
             mDeferRemoval = true;
             return;
         }
-        if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing taskId=" + mTaskId);
+        if (DEBUG_STACK) Slog.i(TAG_WM, "removeTask: removing taskId=" + mTaskId);
         EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, mTaskId, "removeTask");
         mDeferRemoval = false;
         DisplayContent content = getDisplayContent();
@@ -175,7 +174,7 @@
         if (stack == mStack) {
             return;
         }
-        if (DEBUG_STACK) Slog.i(TAG, "moveTaskToStack: removing taskId=" + mTaskId
+        if (DEBUG_STACK) Slog.i(TAG_WM, "moveTaskToStack: removing taskId=" + mTaskId
                 + " from stack=" + mStack);
         EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, mTaskId, "moveTask");
         if (mStack != null) {
@@ -186,7 +185,7 @@
 
     void positionTaskInStack(TaskStack stack, int position, Rect bounds, Configuration config) {
         if (mStack != null && stack != mStack) {
-            if (DEBUG_STACK) Slog.i(TAG, "positionTaskInStack: removing taskId=" + mTaskId
+            if (DEBUG_STACK) Slog.i(TAG_WM, "positionTaskInStack: removing taskId=" + mTaskId
                     + " from stack=" + mStack);
             EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, mTaskId, "moveTask");
             mStack.removeTask(this);
@@ -464,7 +463,7 @@
             for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
                 final WindowState win = windows.get(winNdx);
                 if (!resizingWindows.contains(win)) {
-                    if (DEBUG_RESIZE) Slog.d(TAG, "setBounds: Resizing " + win);
+                    if (DEBUG_RESIZE) Slog.d(TAG_WM, "setBounds: Resizing " + win);
                     resizingWindows.add(win);
                 }
             }
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index 32c3205..725bbbc 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -18,15 +18,18 @@
 
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.RESIZE_MODE_USER;
 import static android.app.ActivityManager.RESIZE_MODE_USER_FORCED;
+import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static com.android.server.wm.DimLayer.RESIZING_HINT_ALPHA;
 import static com.android.server.wm.DimLayer.RESIZING_HINT_DURATION_MS;
-import static com.android.server.wm.WindowManagerService.DEBUG_TASK_POSITIONING;
-import static com.android.server.wm.WindowManagerService.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.dipToPixel;
 import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_HEIGHT_IN_DP;
 import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_WIDTH_IN_DP;
@@ -40,13 +43,13 @@
 import android.os.Trace;
 import android.util.DisplayMetrics;
 import android.util.Slog;
+import android.view.BatchedInputEventReceiver;
 import android.view.Choreographer;
 import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.InputChannel;
 import android.view.InputDevice;
 import android.view.InputEvent;
-import android.view.BatchedInputEventReceiver;
 import android.view.MotionEvent;
 import android.view.SurfaceControl;
 import android.view.WindowManager;
@@ -59,7 +62,7 @@
 import java.lang.annotation.RetentionPolicy;
 
 class TaskPositioner implements DimLayer.DimLayerUser {
-    private static final String TAG = "TaskPositioner";
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskPositioner" : TAG_WM;
 
     // The margin the pointer position has to be within the side of the screen to be
     // considered at the side of the screen.
@@ -277,7 +280,7 @@
         mDragWindowHandle.frameBottom = p.y;
 
         // Pause rotations before a drag.
-        if (WindowManagerService.DEBUG_ORIENTATION) {
+        if (DEBUG_ORIENTATION) {
             Slog.d(TAG, "Pausing rotation during re-position");
         }
         mService.pauseRotationLocked();
@@ -321,7 +324,7 @@
         mDragEnded = true;
 
         // Resume rotations after a drag.
-        if (WindowManagerService.DEBUG_ORIENTATION) {
+        if (DEBUG_ORIENTATION) {
             Slog.d(TAG, "Resuming rotation after re-position");
         }
         mService.resumeRotationLocked();
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 996fadf..49d9efe 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -39,9 +39,9 @@
 import static android.view.WindowManager.DOCKED_LEFT;
 import static android.view.WindowManager.DOCKED_RIGHT;
 import static android.view.WindowManager.DOCKED_TOP;
-import static com.android.server.wm.WindowManagerService.DEBUG_TASK_MOVEMENT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT;
 import static com.android.server.wm.WindowManagerService.H.RESIZE_STACK;
-import static com.android.server.wm.WindowManagerService.TAG;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 public class TaskStack implements DimLayer.DimLayerUser {
 
@@ -138,7 +138,7 @@
                     task.setBounds(bounds, config);
                 }
             } else {
-                Slog.wtf(TAG, "No config for task: " + task + ", is there a mismatch with AM?");
+                Slog.wtf(TAG_WM, "No config for task: " + task + ", is there a mismatch with AM?");
             }
         }
         return true;
@@ -285,7 +285,7 @@
         // Reset position based on minimum/maximum possible positions.
         position = Math.min(Math.max(position, minPosition), maxPosition);
 
-        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG,
+        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG_WM,
                 "positionTask: task=" + task + " position=" + position);
         mTasks.add(position, task);
 
@@ -338,14 +338,14 @@
     }
 
     void moveTaskToTop(Task task) {
-        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "moveTaskToTop: task=" + task + " Callers="
+        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG_WM, "moveTaskToTop: task=" + task + " Callers="
                 + Debug.getCallers(6));
         mTasks.remove(task);
         addTask(task, true);
     }
 
     void moveTaskToBottom(Task task) {
-        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "moveTaskToBottom: task=" + task);
+        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG_WM, "moveTaskToBottom: task=" + task);
         mTasks.remove(task);
         addTask(task, false);
     }
@@ -356,7 +356,7 @@
      * @param task The Task to delete.
      */
     void removeTask(Task task) {
-        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "removeTask: task=" + task);
+        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG_WM, "removeTask: task=" + task);
         mTasks.remove(task);
         if (mDisplayContent != null) {
             if (mTasks.isEmpty()) {
@@ -433,7 +433,7 @@
         final int dockedSide = dockedStack.getDockSide();
         if (dockedSide == DOCKED_INVALID) {
             // Not sure how you got here...Only thing we can do is return current bounds.
-            Slog.e(TAG, "Failed to get valid docked side for docked stack=" + dockedStack);
+            Slog.e(TAG_WM, "Failed to get valid docked side for docked stack=" + dockedStack);
             outBounds.set(mBounds);
             return;
         }
diff --git a/services/core/java/com/android/server/wm/ViewServer.java b/services/core/java/com/android/server/wm/ViewServer.java
index 741cee3..ecf5652 100644
--- a/services/core/java/com/android/server/wm/ViewServer.java
+++ b/services/core/java/com/android/server/wm/ViewServer.java
@@ -17,6 +17,9 @@
 package com.android.server.wm;
 
 
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
 import android.util.Slog;
 
 import java.net.ServerSocket;
@@ -47,7 +50,7 @@
     private static final int VIEW_SERVER_MAX_CONNECTIONS = 10;
 
     // Debug facility
-    private static final String LOG_TAG = "ViewServer";
+    private static final String LOG_TAG = TAG_WITH_CLASS_NAME ? "ViewServer" : TAG_WM;
 
     private static final String VALUE_PROTOCOL_VERSION = "4";
     private static final String VALUE_SERVER_VERSION = "4";
@@ -150,7 +153,7 @@
      *
      * @see #start()
      * @see #stop()
-     * @see WindowManagerService#isViewServerRunning()  
+     * @see WindowManagerService#isViewServerRunning()
      */
     boolean isRunning() {
         return mThread != null && mThread.isAlive();
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 8b984f0..3db9ae0 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -22,13 +22,15 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
-import static com.android.server.wm.WindowManagerService.DEBUG_ADD_REMOVE;
-import static com.android.server.wm.WindowManagerService.DEBUG_APP_TRANSITIONS;
-import static com.android.server.wm.WindowManagerService.DEBUG_LAYERS;
-import static com.android.server.wm.WindowManagerService.DEBUG_WINDOW_MOVEMENT;
-import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
-import static com.android.server.wm.WindowManagerService.DEBUG_WALLPAPER;
-import static com.android.server.wm.WindowManagerService.DEBUG_WALLPAPER_LIGHT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.H.WALLPAPER_DRAW_PENDING_TIMEOUT;
 import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
 import static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET;
@@ -51,7 +53,7 @@
  * NOTE: All methods in this class must be called with the window manager service lock held.
  */
 class WallpaperController {
-    private static final String TAG = com.android.server.wm.WindowManagerService.TAG;
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "WallpaperController" : TAG_WM;
     final private WindowManagerService mService;
 
     private final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<>();
diff --git a/services/core/java/com/android/server/wm/Watermark.java b/services/core/java/com/android/server/wm/Watermark.java
index e226e3d..171e575 100644
--- a/services/core/java/com/android/server/wm/Watermark.java
+++ b/services/core/java/com/android/server/wm/Watermark.java
@@ -16,6 +16,8 @@
 
 package com.android.server.wm;
 
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.PixelFormat;
@@ -53,9 +55,9 @@
 
     Watermark(Display display, DisplayMetrics dm, SurfaceSession session, String[] tokens) {
         if (false) {
-            Log.i(WindowManagerService.TAG, "*********************** WATERMARK");
+            Log.i(TAG_WM, "*********************** WATERMARK");
             for (int i=0; i<tokens.length; i++) {
-                Log.i(WindowManagerService.TAG, "  TOKEN #" + i + ": " + tokens[i]);
+                Log.i(TAG_WM, "  TOKEN #" + i + ": " + tokens[i]);
             }
         }
 
@@ -78,7 +80,7 @@
         }
         mText = builder.toString();
         if (false) {
-            Log.i(WindowManagerService.TAG, "Final text: " + mText);
+            Log.i(TAG_WM, "Final text: " + mText);
         }
 
         int fontSize = WindowManagerService.getPropertyInt(tokens, 1,
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index f20c4e5..a6523a4 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -21,15 +21,17 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-import static com.android.server.wm.WindowManagerService.DEBUG_ANIM;
-import static com.android.server.wm.WindowManagerService.DEBUG_FOCUS_LIGHT;
-import static com.android.server.wm.WindowManagerService.DEBUG_KEYGUARD;
-import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT_REPEATS;
-import static com.android.server.wm.WindowManagerService.DEBUG_ORIENTATION;
-import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
-import static com.android.server.wm.WindowManagerService.DEBUG_WALLPAPER;
-import static com.android.server.wm.WindowManagerService.DEBUG_WINDOW_TRACE;
-import static com.android.server.wm.WindowManagerService.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEYGUARD;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED;
 import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
 import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
@@ -56,7 +58,7 @@
  * on behalf of WindowManagerService.
  */
 public class WindowAnimator {
-    private static final String TAG = "WindowAnimator";
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowAnimator" : TAG_WM;
 
     /** How long to give statusbar to clear the private keyguard flag when animating out */
     private static final long KEYGUARD_ANIM_TIMEOUT_MS = 1000;
diff --git a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
new file mode 100644
index 0000000..a49bb31
--- /dev/null
+++ b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.server.wm;
+
+/**
+ * Common class for the various debug {@link android.util.Log} output configuration in the window
+ * manager package.
+ */
+public class WindowManagerDebugConfig {
+    // All output logs in the window manager package use the {@link #TAG_WM} string for tagging
+    // their log output. This makes it easy to identify the origin of the log message when sifting
+    // through a large amount of log output from multiple sources. However, it also makes trying
+    // to figure-out the origin of a log message while debugging the window manager a little
+    // painful. By setting this constant to true, log messages from the window manager package
+    // will be tagged with their class names instead fot the generic tag.
+    static final boolean TAG_WITH_CLASS_NAME = false;
+
+    // Default log tag for the window manager package.
+    static final String TAG_WM = "WindowManager";
+
+    static final boolean DEBUG_RESIZE = false;
+    static final boolean DEBUG = false;
+    static final boolean DEBUG_ADD_REMOVE = false;
+    static final boolean DEBUG_FOCUS = false;
+    static final boolean DEBUG_FOCUS_LIGHT = DEBUG_FOCUS || false;
+    static final boolean DEBUG_ANIM = false;
+    static final boolean DEBUG_KEYGUARD = false;
+    static final boolean DEBUG_LAYOUT = false;
+    static final boolean DEBUG_LAYERS = false;
+    static final boolean DEBUG_INPUT = false;
+    static final boolean DEBUG_INPUT_METHOD = false;
+    static final boolean DEBUG_VISIBILITY = false;
+    static final boolean DEBUG_WINDOW_MOVEMENT = false;
+    static final boolean DEBUG_TOKEN_MOVEMENT = false;
+    static final boolean DEBUG_ORIENTATION = false;
+    static final boolean DEBUG_APP_ORIENTATION = false;
+    static final boolean DEBUG_CONFIGURATION = false;
+    static final boolean DEBUG_APP_TRANSITIONS = false;
+    static final boolean DEBUG_STARTING_WINDOW = false;
+    static final boolean DEBUG_WALLPAPER = false;
+    static final boolean DEBUG_WALLPAPER_LIGHT = false || DEBUG_WALLPAPER;
+    static final boolean DEBUG_DRAG = false;
+    static final boolean DEBUG_SCREEN_ON = false;
+    static final boolean DEBUG_SCREENSHOT = false;
+    static final boolean DEBUG_BOOT = false;
+    static final boolean DEBUG_LAYOUT_REPEATS = true;
+    static final boolean DEBUG_SURFACE_TRACE = false;
+    static final boolean DEBUG_WINDOW_TRACE = false;
+    static final boolean DEBUG_TASK_MOVEMENT = false;
+    static final boolean DEBUG_TASK_POSITIONING = false;
+    static final boolean DEBUG_STACK = false;
+    static final boolean DEBUG_DISPLAY = false;
+    static final boolean DEBUG_POWER = false;
+    static final boolean DEBUG_DIM_LAYER = false;
+    static final boolean SHOW_SURFACE_ALLOC = false;
+    static final boolean SHOW_TRANSACTIONS = false;
+    static final boolean SHOW_VERBOSE_TRANSACTIONS = false && SHOW_TRANSACTIONS;
+    static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
+    static final boolean HIDE_STACK_CRAWLS = true;
+    static final boolean DEBUG_WINDOW_CROP = false;
+}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 410d810..0c606fe 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -20,8 +20,8 @@
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
 import static android.app.StatusBarManager.DISABLE_MASK;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.view.WindowManager.DOCKED_INVALID;
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
@@ -50,15 +50,47 @@
 import static android.view.WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY;
 import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-
 import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_END;
 import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_START;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_ORIENTATION;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEYGUARD;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
+import static com.android.server.wm.WindowManagerDebugConfig.HIDE_STACK_CRAWLS;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_VERBOSE_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 import android.Manifest;
 import android.animation.ValueAnimator;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.ActivityManager;
 import android.app.ActivityManager.StackId;
 import android.app.ActivityManagerNative;
 import android.app.AppOpsManager;
@@ -122,8 +154,8 @@
 import android.view.DisplayInfo;
 import android.view.DropPermissionHolder;
 import android.view.Gravity;
-import android.view.IApplicationToken;
 import android.view.IAppTransitionAnimationSpecsFuture;
+import android.view.IApplicationToken;
 import android.view.IDockDividerVisibilityListener;
 import android.view.IInputFilter;
 import android.view.IOnKeyguardExitResult;
@@ -155,8 +187,8 @@
 import android.view.animation.Animation;
 import android.widget.Toast;
 
-import com.android.internal.app.IAssistScreenshotReceiver;
 import com.android.internal.R;
+import com.android.internal.app.IAssistScreenshotReceiver;
 import com.android.internal.util.FastPrintWriter;
 import com.android.internal.view.IInputContext;
 import com.android.internal.view.IInputMethodClient;
@@ -196,46 +228,6 @@
 /** {@hide} */
 public class WindowManagerService extends IWindowManager.Stub
         implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
-    static final String TAG = "WindowManager";
-    static final boolean DEBUG = false;
-    static final boolean DEBUG_ADD_REMOVE = false;
-    static final boolean DEBUG_FOCUS = false;
-    static final boolean DEBUG_FOCUS_LIGHT = DEBUG_FOCUS || false;
-    static final boolean DEBUG_ANIM = false;
-    static final boolean DEBUG_KEYGUARD = false;
-    static final boolean DEBUG_LAYOUT = false;
-    static final boolean DEBUG_RESIZE = false;
-    static final boolean DEBUG_LAYERS = false;
-    static final boolean DEBUG_INPUT = false;
-    static final boolean DEBUG_INPUT_METHOD = false;
-    static final boolean DEBUG_VISIBILITY = false;
-    static final boolean DEBUG_WINDOW_MOVEMENT = false;
-    static final boolean DEBUG_TOKEN_MOVEMENT = false;
-    static final boolean DEBUG_ORIENTATION = false;
-    static final boolean DEBUG_APP_ORIENTATION = false;
-    static final boolean DEBUG_CONFIGURATION = false;
-    static final boolean DEBUG_APP_TRANSITIONS = false;
-    static final boolean DEBUG_STARTING_WINDOW = false;
-    static final boolean DEBUG_WALLPAPER = false;
-    static final boolean DEBUG_WALLPAPER_LIGHT = false || DEBUG_WALLPAPER;
-    static final boolean DEBUG_DRAG = false;
-    static final boolean DEBUG_SCREEN_ON = false;
-    static final boolean DEBUG_SCREENSHOT = false;
-    static final boolean DEBUG_BOOT = false;
-    static final boolean DEBUG_LAYOUT_REPEATS = true;
-    static final boolean DEBUG_SURFACE_TRACE = false;
-    static final boolean DEBUG_WINDOW_TRACE = false;
-    static final boolean DEBUG_TASK_MOVEMENT = false;
-    static final boolean DEBUG_TASK_POSITIONING = false;
-    static final boolean DEBUG_STACK = false;
-    static final boolean DEBUG_DISPLAY = false;
-    static final boolean DEBUG_POWER = false;
-    static final boolean DEBUG_DIM_LAYER = false;
-    static final boolean SHOW_SURFACE_ALLOC = false;
-    static final boolean SHOW_TRANSACTIONS = false;
-    static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
-    static final boolean SHOW_VERBOSE_TRANSACTIONS = false && SHOW_TRANSACTIONS;
-    static final boolean HIDE_STACK_CRAWLS = true;
     static final int LAYOUT_REPEAT_THRESHOLD = 4;
 
     static final boolean PROFILE_ORIENTATION = false;
@@ -526,7 +518,7 @@
     boolean mClientFreezingScreen = false;
     int mAppsFreezingScreen = 0;
     int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-    int mLastKeyguardForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+    int mLastKeyguardForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 
     int mLayoutSeq = 0;
 
@@ -706,13 +698,13 @@
                     switch (motionEvent.getAction()) {
                     case MotionEvent.ACTION_DOWN: {
                         if (DEBUG_DRAG) {
-                            Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
+                            Slog.w(TAG_WM, "Unexpected ACTION_DOWN in drag layer");
                         }
                     } break;
 
                     case MotionEvent.ACTION_MOVE: {
                         if (mStylusButtonDownAtStart && !isStylusButtonDown) {
-                            if (DEBUG_DRAG) Slog.d(TAG, "Button no longer pressed; dropping at "
+                            if (DEBUG_DRAG) Slog.d(TAG_WM, "Button no longer pressed; dropping at "
                                     + newX + "," + newY);
                             synchronized (mWindowMap) {
                                 endDrag = completeDropLw(newX, newY);
@@ -726,7 +718,7 @@
                     } break;
 
                     case MotionEvent.ACTION_UP: {
-                        if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
+                        if (DEBUG_DRAG) Slog.d(TAG_WM, "Got UP on move channel; dropping at "
                                 + newX + "," + newY);
                         synchronized (mWindowMap) {
                             endDrag = completeDropLw(newX, newY);
@@ -734,13 +726,13 @@
                     } break;
 
                     case MotionEvent.ACTION_CANCEL: {
-                        if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
+                        if (DEBUG_DRAG) Slog.d(TAG_WM, "Drag cancelled!");
                         endDrag = true;
                     } break;
                     }
 
                     if (endDrag) {
-                        if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
+                        if (DEBUG_DRAG) Slog.d(TAG_WM, "Drag ended; tearing down state");
                         // tell all the windows that the drag has ended
                         synchronized (mWindowMap) {
                             mDragState.endDragLw();
@@ -752,7 +744,7 @@
                     handled = true;
                 }
             } catch (Exception e) {
-                Slog.e(TAG, "Exception caught by drag handleMotion", e);
+                Slog.e(TAG_WM, "Exception caught by drag handleMotion", e);
             } finally {
                 finishInputEvent(event, handled);
             }
@@ -889,7 +881,7 @@
 
         LocalServices.addService(WindowManagerPolicy.class, mPolicy);
 
-        mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG));
+        mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG_WM));
 
         mFxSession = new SurfaceSession();
         mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
@@ -950,7 +942,7 @@
         updateShowImeWithHardKeyboard();
 
         mHoldingScreenWakeLock = mPowerManager.newWakeLock(
-                PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG);
+                PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG_WM);
         mHoldingScreenWakeLock.setReferenceCounted(false);
 
         mAnimator = new WindowAnimator(this);
@@ -988,7 +980,7 @@
             // The window manager only throws security exceptions, so let's
             // log all others.
             if (!(e instanceof SecurityException)) {
-                Slog.wtf(TAG, "Window Manager Crash", e);
+                Slog.wtf(TAG_WM, "Window Manager Crash", e);
             }
             throw e;
         }
@@ -998,7 +990,7 @@
         final WindowList windows = pos.getWindowList();
         final int i = windows.indexOf(pos);
         if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
-            TAG, "Adding window " + window + " at "
+            TAG_WM, "Adding window " + window + " at "
             + (i+1) + " of " + windows.size() + " (after " + pos + ")");
         windows.add(i+1, window);
         mWindowsChanged = true;
@@ -1008,10 +1000,10 @@
         final WindowList windows = pos.getWindowList();
         int i = windows.indexOf(pos);
         if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
-            TAG, "Adding window " + window + " at "
+            TAG_WM, "Adding window " + window + " at "
             + i + " of " + windows.size() + " (before " + pos + ")");
         if (i < 0) {
-            Slog.w(TAG, "placeWindowBefore: Unable to find " + pos + " in " + windows);
+            Slog.w(TAG_WM, "placeWindowBefore: Unable to find " + pos + " in " + windows);
             i = 0;
         }
         windows.add(i, window);
@@ -1087,7 +1079,7 @@
         }
 
         // No windows from this token on this display
-        if (localLOGV) Slog.v(TAG, "Figuring out where to add app window " + client.asBinder()
+        if (localLOGV) Slog.v(TAG_WM, "Figuring out where to add app window " + client.asBinder()
                 + " (token=" + token + ")");
         // Figure out where the window should go, based on the
         // order of applications.
@@ -1195,7 +1187,7 @@
                 break;
             }
         }
-        if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
+        if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
                 "Based on layer: Adding window " + win + " at " + (i + 1) + " of "
                         + windows.size());
         windows.add(i + 1, win);
@@ -1227,7 +1219,7 @@
                 //apptoken note that the window could be a floating window
                 //that was created later or a window at the top of the list of
                 //windows associated with this token.
-                if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
+                if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
                         "not Base app: Adding window " + win + " at " + (newIdx + 1) + " of "
                                 + windows.size());
                 windows.add(newIdx + 1, win);
@@ -1265,7 +1257,7 @@
             }
         }
         i++;
-        if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
+        if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
                 "Free window: Adding window " + win + " at " + i + " of " + windows.size());
         windows.add(i, win);
         mWindowsChanged = true;
@@ -1300,7 +1292,7 @@
                 // in the same sublayer.
                 if (wSublayer >= sublayer) {
                     if (addToToken) {
-                        if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
+                        if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Adding " + win + " to " + token);
                         token.windows.add(i, win);
                     }
                     placeWindowBefore(wSublayer >= 0 ? attached : w, win);
@@ -1311,7 +1303,7 @@
                 // in the same sublayer.
                 if (wSublayer > sublayer) {
                     if (addToToken) {
-                        if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
+                        if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Adding " + win + " to " + token);
                         token.windows.add(i, win);
                     }
                     placeWindowBefore(w, win);
@@ -1321,7 +1313,7 @@
         }
         if (i >= NA) {
             if (addToToken) {
-                if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
+                if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Adding " + win + " to " + token);
                 token.windows.add(win);
             }
             if (sublayer < 0) {
@@ -1336,7 +1328,7 @@
     }
 
     private void addWindowToListInOrderLocked(final WindowState win, boolean addToToken) {
-        if (DEBUG_FOCUS_LIGHT) Slog.d(TAG, "addWindowToListInOrderLocked: win=" + win +
+        if (DEBUG_FOCUS_LIGHT) Slog.d(TAG_WM, "addWindowToListInOrderLocked: win=" + win +
                 " Callers=" + Debug.getCallers(4));
         if (win.mAttachedWindow == null) {
             final WindowToken token = win.mToken;
@@ -1347,7 +1339,7 @@
                 addFreeWindowToListLocked(win);
             }
             if (addToToken) {
-                if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
+                if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Adding " + win + " to " + token);
                 token.windows.add(tokenWindowsPos, win);
             }
         } else {
@@ -1375,9 +1367,9 @@
         if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)
                 || type == TYPE_APPLICATION_STARTING || type == TYPE_DOCK_DIVIDER) {
             if (DEBUG_INPUT_METHOD) {
-                Slog.i(TAG, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
+                Slog.i(TAG_WM, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
                 if (!w.isVisibleOrAdding()) {
-                    Slog.i(TAG, "  mSurfaceController=" + w.mWinAnimator.mSurfaceController
+                    Slog.i(TAG_WM, "  mSurfaceController=" + w.mWinAnimator.mSurfaceController
                             + " relayoutCalled=" + w.mRelayoutCalled
                             + " viewVis=" + w.mViewVisibility
                             + " policyVis=" + w.mPolicyVisibility
@@ -1385,7 +1377,7 @@
                             + " attachHid=" + w.mAttachedHidden
                             + " exiting=" + w.mExiting + " destroying=" + w.mDestroying);
                     if (w.mAppToken != null) {
-                        Slog.i(TAG, "  mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
+                        Slog.i(TAG_WM, "  mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
                     }
                 }
             }
@@ -1409,11 +1401,11 @@
         for (i = windows.size() - 1; i >= 0; --i) {
             WindowState win = windows.get(i);
 
-            if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG, "Checking window @" + i
+            if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG_WM, "Checking window @" + i
                     + " " + win + " fl=0x" + Integer.toHexString(win.mAttrs.flags));
             if (canBeImeTarget(win)) {
                 w = win;
-                //Slog.i(TAG, "Putting input method here!");
+                //Slog.i(TAG_WM, "Putting input method here!");
 
                 // Yet more tricksyness!  If this window is a "starting"
                 // window, we do actually want to be on top of it, but
@@ -1435,7 +1427,7 @@
 
         // Now w is either mWindows[0] or an IME (or null if mWindows is empty).
 
-        if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG, "Proposed new IME target: " + w);
+        if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG_WM, "Proposed new IME target: " + w);
 
         // Now, a special case -- if the last target's window is in the
         // process of exiting, and is above the new target, keep on the
@@ -1448,11 +1440,11 @@
                 && curTarget.isDisplayedLw()
                 && curTarget.isClosing()
                 && (w == null || curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer)) {
-            if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Current target higher, not changing");
+            if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Current target higher, not changing");
             return windows.indexOf(curTarget) + 1;
         }
 
-        if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
+        if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Desired input method target="
                 + w + " willMove=" + willMove);
 
         if (willMove && w != null) {
@@ -1485,7 +1477,7 @@
                 }
 
                 if (highestTarget != null) {
-                    if (DEBUG_INPUT_METHOD) Slog.v(TAG, mAppTransition + " " + highestTarget
+                    if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, mAppTransition + " " + highestTarget
                             + " animating=" + highestTarget.mWinAnimator.isAnimating()
                             + " layer=" + highestTarget.mWinAnimator.mAnimLayer
                             + " new layer=" + w.mWinAnimator.mAnimLayer);
@@ -1510,10 +1502,10 @@
             }
         }
 
-        //Slog.i(TAG, "Placing input method @" + (i+1));
+        //Slog.i(TAG_WM, "Placing input method @" + (i+1));
         if (w != null) {
             if (willMove) {
-                if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to "
+                if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to "
                         + w + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
                 mInputMethodTarget = w;
                 mInputMethodTargetWaitingAnim = false;
@@ -1526,7 +1518,7 @@
             return i+1;
         }
         if (willMove) {
-            if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to null."
+            if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to null."
                     + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
             mInputMethodTarget = null;
             setInputMethodAnimLayerAdjustment(0);
@@ -1539,7 +1531,7 @@
         if (pos >= 0) {
             win.mTargetAppToken = mInputMethodTarget.mAppToken;
             if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
-                    TAG, "Adding input method window " + win + " at " + pos);
+                    TAG_WM, "Adding input method window " + win + " at " + pos);
             // TODO(multidisplay): IMEs are only supported on the default display.
             getDefaultWindowListLocked().add(pos, win);
             mWindowsChanged = true;
@@ -1552,19 +1544,19 @@
     }
 
     void setInputMethodAnimLayerAdjustment(int adj) {
-        if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
+        if (DEBUG_LAYERS) Slog.v(TAG_WM, "Setting im layer adj to " + adj);
         mInputMethodAnimLayerAdjustment = adj;
         WindowState imw = mInputMethodWindow;
         if (imw != null) {
             imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
-            if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
+            if (DEBUG_LAYERS) Slog.v(TAG_WM, "IM win " + imw
                     + " anim layer: " + imw.mWinAnimator.mAnimLayer);
             int wi = imw.mChildWindows.size();
             while (wi > 0) {
                 wi--;
                 WindowState cw = imw.mChildWindows.get(wi);
                 cw.mWinAnimator.mAnimLayer = cw.mLayer + adj;
-                if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
+                if (DEBUG_LAYERS) Slog.v(TAG_WM, "IM win " + cw
                         + " anim layer: " + cw.mWinAnimator.mAnimLayer);
             }
         }
@@ -1573,7 +1565,7 @@
             di --;
             imw = mInputMethodDialogs.get(di);
             imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
-            if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
+            if (DEBUG_LAYERS) Slog.v(TAG_WM, "IM win " + imw
                     + " anim layer: " + imw.mWinAnimator.mAnimLayer);
         }
     }
@@ -1583,7 +1575,7 @@
         int wpos = windows.indexOf(win);
         if (wpos >= 0) {
             if (wpos < interestingPos) interestingPos--;
-            if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
+            if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Temp removing at " + wpos + ": " + win);
             windows.remove(wpos);
             mWindowsChanged = true;
             int NC = win.mChildWindows.size();
@@ -1593,7 +1585,7 @@
                 int cpos = windows.indexOf(cw);
                 if (cpos >= 0) {
                     if (cpos < interestingPos) interestingPos--;
-                    if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
+                    if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Temp removing child at "
                             + cpos + ": " + cw);
                     windows.remove(cpos);
                 }
@@ -1610,7 +1602,7 @@
         WindowList windows = win.getWindowList();
         int wpos = windows.indexOf(win);
         if (wpos >= 0) {
-            if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos + ": " + win);
+            if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "ReAdd removing from " + wpos + ": " + win);
             windows.remove(wpos);
             mWindowsChanged = true;
             reAddWindowLocked(wpos, win);
@@ -1621,7 +1613,7 @@
         int N = windows.size();
         while (N > 0) {
             N--;
-            Slog.v(TAG, prefix + "#" + N + ": " + windows.get(N));
+            Slog.v(TAG_WM, prefix + "#" + N + ": " + windows.get(N));
         }
     }
 
@@ -1631,12 +1623,12 @@
         // TODO(multidisplay): IMEs are only supported on the default display.
         WindowList windows = getDefaultWindowListLocked();
         final int N = dialogs.size();
-        if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
+        if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Removing " + N + " dialogs w/pos=" + pos);
         for (int i=0; i<N; i++) {
             pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
         }
         if (DEBUG_INPUT_METHOD) {
-            Slog.v(TAG, "Window list w/pos=" + pos);
+            Slog.v(TAG_WM, "Window list w/pos=" + pos);
             logWindowList(windows, "  ");
         }
 
@@ -1653,14 +1645,14 @@
                     break;
                 }
             }
-            if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
+            if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Adding " + N + " dialogs at pos=" + pos);
             for (int i=0; i<N; i++) {
                 WindowState win = dialogs.get(i);
                 win.mTargetAppToken = targetAppToken;
                 pos = reAddWindowLocked(pos, win);
             }
             if (DEBUG_INPUT_METHOD) {
-                Slog.v(TAG, "Final window list:");
+                Slog.v(TAG_WM, "Final window list:");
                 logWindowList(windows, "  ");
             }
             return;
@@ -1670,7 +1662,7 @@
             win.mTargetAppToken = null;
             reAddWindowToListInOrderLocked(win);
             if (DEBUG_INPUT_METHOD) {
-                Slog.v(TAG, "No IM target, final list:");
+                Slog.v(TAG_WM, "No IM target, final list:");
                 logWindowList(windows, "  ");
             }
         }
@@ -1736,18 +1728,18 @@
 
             if (imWin != null) {
                 if (DEBUG_INPUT_METHOD) {
-                    Slog.v(TAG, "Moving IM from " + imPos);
+                    Slog.v(TAG_WM, "Moving IM from " + imPos);
                     logWindowList(windows, "  ");
                 }
                 imPos = tmpRemoveWindowLocked(imPos, imWin);
                 if (DEBUG_INPUT_METHOD) {
-                    Slog.v(TAG, "List after removing with new pos " + imPos + ":");
+                    Slog.v(TAG_WM, "List after removing with new pos " + imPos + ":");
                     logWindowList(windows, "  ");
                 }
                 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
                 reAddWindowLocked(imPos, imWin);
                 if (DEBUG_INPUT_METHOD) {
-                    Slog.v(TAG, "List after moving IM to " + imPos + ":");
+                    Slog.v(TAG_WM, "List after moving IM to " + imPos + ":");
                     logWindowList(windows, "  ");
                 }
                 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
@@ -1760,12 +1752,12 @@
             // because they aren't currently associated with a focus window.
 
             if (imWin != null) {
-                if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
+                if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Moving IM from " + imPos);
                 tmpRemoveWindowLocked(0, imWin);
                 imWin.mTargetAppToken = null;
                 reAddWindowToListInOrderLocked(imWin);
                 if (DEBUG_INPUT_METHOD) {
-                    Slog.v(TAG, "List with no IM target:");
+                    Slog.v(TAG_WM, "List with no IM target:");
                     logWindowList(windows, "  ");
                 }
                 if (DN > 0) moveInputMethodDialogsLocked(-1);
@@ -1804,38 +1796,38 @@
 
             final DisplayContent displayContent = getDisplayContentLocked(displayId);
             if (displayContent == null) {
-                Slog.w(TAG, "Attempted to add window to a display that does not exist: "
+                Slog.w(TAG_WM, "Attempted to add window to a display that does not exist: "
                         + displayId + ".  Aborting.");
                 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
             }
             if (!displayContent.hasAccess(session.mUid)) {
-                Slog.w(TAG, "Attempted to add window to a display for which the application "
+                Slog.w(TAG_WM, "Attempted to add window to a display for which the application "
                         + "does not have access: " + displayId + ".  Aborting.");
                 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
             }
 
             if (mWindowMap.containsKey(client.asBinder())) {
-                Slog.w(TAG, "Window " + client + " is already added");
+                Slog.w(TAG_WM, "Window " + client + " is already added");
                 return WindowManagerGlobal.ADD_DUPLICATE_ADD;
             }
 
             if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {
                 attachedWindow = windowForClientLocked(null, attrs.token, false);
                 if (attachedWindow == null) {
-                    Slog.w(TAG, "Attempted to add window with token that is not a window: "
+                    Slog.w(TAG_WM, "Attempted to add window with token that is not a window: "
                           + attrs.token + ".  Aborting.");
                     return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
                 }
                 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
                         && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
-                    Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
+                    Slog.w(TAG_WM, "Attempted to add window with token that is a sub-window: "
                             + attrs.token + ".  Aborting.");
                     return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
                 }
             }
 
             if (type == TYPE_PRIVATE_PRESENTATION && !displayContent.isPrivate()) {
-                Slog.w(TAG, "Attempted to add private presentation window to a non-private display.  Aborting.");
+                Slog.w(TAG_WM, "Attempted to add private presentation window to a non-private display.  Aborting.");
                 return WindowManagerGlobal.ADD_PERMISSION_DENIED;
             }
 
@@ -1844,37 +1836,37 @@
             AppWindowToken atoken = null;
             if (token == null) {
                 if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
-                    Slog.w(TAG, "Attempted to add application window with unknown token "
+                    Slog.w(TAG_WM, "Attempted to add application window with unknown token "
                           + attrs.token + ".  Aborting.");
                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                 }
                 if (type == TYPE_INPUT_METHOD) {
-                    Slog.w(TAG, "Attempted to add input method window with unknown token "
+                    Slog.w(TAG_WM, "Attempted to add input method window with unknown token "
                           + attrs.token + ".  Aborting.");
                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                 }
                 if (type == TYPE_VOICE_INTERACTION) {
-                    Slog.w(TAG, "Attempted to add voice interaction window with unknown token "
+                    Slog.w(TAG_WM, "Attempted to add voice interaction window with unknown token "
                           + attrs.token + ".  Aborting.");
                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                 }
                 if (type == TYPE_WALLPAPER) {
-                    Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
+                    Slog.w(TAG_WM, "Attempted to add wallpaper window with unknown token "
                           + attrs.token + ".  Aborting.");
                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                 }
                 if (type == TYPE_DREAM) {
-                    Slog.w(TAG, "Attempted to add Dream window with unknown token "
+                    Slog.w(TAG_WM, "Attempted to add Dream window with unknown token "
                           + attrs.token + ".  Aborting.");
                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                 }
                 if (type == TYPE_QS_DIALOG) {
-                    Slog.w(TAG, "Attempted to add QS dialog window with unknown token "
+                    Slog.w(TAG_WM, "Attempted to add QS dialog window with unknown token "
                           + attrs.token + ".  Aborting.");
                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                 }
                 if (type == TYPE_ACCESSIBILITY_OVERLAY) {
-                    Slog.w(TAG, "Attempted to add Accessibility overlay window with unknown token "
+                    Slog.w(TAG_WM, "Attempted to add Accessibility overlay window with unknown token "
                             + attrs.token + ".  Aborting.");
                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                 }
@@ -1883,52 +1875,52 @@
             } else if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
                 atoken = token.appWindowToken;
                 if (atoken == null) {
-                    Slog.w(TAG, "Attempted to add window with non-application token "
+                    Slog.w(TAG_WM, "Attempted to add window with non-application token "
                           + token + ".  Aborting.");
                     return WindowManagerGlobal.ADD_NOT_APP_TOKEN;
                 } else if (atoken.removed) {
-                    Slog.w(TAG, "Attempted to add window with exiting application token "
+                    Slog.w(TAG_WM, "Attempted to add window with exiting application token "
                           + token + ".  Aborting.");
                     return WindowManagerGlobal.ADD_APP_EXITING;
                 }
                 if (type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
                     // No need for this guy!
                     if (DEBUG_STARTING_WINDOW || localLOGV) Slog.v(
-                            TAG, "**** NO NEED TO START: " + attrs.getTitle());
+                            TAG_WM, "**** NO NEED TO START: " + attrs.getTitle());
                     return WindowManagerGlobal.ADD_STARTING_NOT_NEEDED;
                 }
             } else if (type == TYPE_INPUT_METHOD) {
                 if (token.windowType != TYPE_INPUT_METHOD) {
-                    Slog.w(TAG, "Attempted to add input method window with bad token "
+                    Slog.w(TAG_WM, "Attempted to add input method window with bad token "
                             + attrs.token + ".  Aborting.");
                       return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                 }
             } else if (type == TYPE_VOICE_INTERACTION) {
                 if (token.windowType != TYPE_VOICE_INTERACTION) {
-                    Slog.w(TAG, "Attempted to add voice interaction window with bad token "
+                    Slog.w(TAG_WM, "Attempted to add voice interaction window with bad token "
                             + attrs.token + ".  Aborting.");
                       return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                 }
             } else if (type == TYPE_WALLPAPER) {
                 if (token.windowType != TYPE_WALLPAPER) {
-                    Slog.w(TAG, "Attempted to add wallpaper window with bad token "
+                    Slog.w(TAG_WM, "Attempted to add wallpaper window with bad token "
                             + attrs.token + ".  Aborting.");
                       return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                 }
             } else if (type == TYPE_DREAM) {
                 if (token.windowType != TYPE_DREAM) {
-                    Slog.w(TAG, "Attempted to add Dream window with bad token "
+                    Slog.w(TAG_WM, "Attempted to add Dream window with bad token "
                             + attrs.token + ".  Aborting.");
                       return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                 }
             } else if (type == TYPE_ACCESSIBILITY_OVERLAY) {
                 if (token.windowType != TYPE_ACCESSIBILITY_OVERLAY) {
-                    Slog.w(TAG, "Attempted to add Accessibility overlay window with bad token "
+                    Slog.w(TAG_WM, "Attempted to add Accessibility overlay window with bad token "
                             + attrs.token + ".  Aborting.");
                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                 }
             } else if (token.appWindowToken != null) {
-                Slog.w(TAG, "Non-null appWindowToken for system window of type=" + type);
+                Slog.w(TAG_WM, "Non-null appWindowToken for system window of type=" + type);
                 // It is not valid to use an app token with other system types; we will
                 // instead make a new token for it (as if null had been passed in for the token).
                 attrs.token = null;
@@ -1941,18 +1933,18 @@
             if (win.mDeathRecipient == null) {
                 // Client has apparently died, so there is no reason to
                 // continue.
-                Slog.w(TAG, "Adding window client " + client.asBinder()
+                Slog.w(TAG_WM, "Adding window client " + client.asBinder()
                         + " that is dead, aborting.");
                 return WindowManagerGlobal.ADD_APP_EXITING;
             }
 
             if (win.getDisplayContent() == null) {
-                Slog.w(TAG, "Adding window to Display that has been removed.");
+                Slog.w(TAG_WM, "Adding window to Display that has been removed.");
                 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
             }
 
             if (atoken != null && atoken.appDied) {
-                Slog.d(TAG, "App is now revived: " + atoken);
+                Slog.d(TAG_WM, "App is now revived: " + atoken);
                 atoken.appDied = false;
             }
 
@@ -1992,7 +1984,7 @@
 
             if (type == TYPE_APPLICATION_STARTING && token.appWindowToken != null) {
                 token.appWindowToken.startingWindow = win;
-                if (DEBUG_STARTING_WINDOW) Slog.v (TAG, "addWindow: " + token.appWindowToken
+                if (DEBUG_STARTING_WINDOW) Slog.v (TAG_WM, "addWindow: " + token.appWindowToken
                         + " startingWindow=" + win);
             }
 
@@ -2073,7 +2065,7 @@
             }
             mInputMonitor.updateInputWindowsLw(false /*force*/);
 
-            if (localLOGV || DEBUG_ADD_REMOVE) Slog.v(TAG, "addWindow: New client "
+            if (localLOGV || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "addWindow: New client "
                     + client.asBinder() + ": window=" + win + " Callers=" + Debug.getCallers(5));
 
             if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) {
@@ -2178,11 +2170,11 @@
     void removeWindowLocked(WindowState win) {
         final boolean startingWindow = win.mAttrs.type == TYPE_APPLICATION_STARTING;
         if (startingWindow) {
-            if (DEBUG_STARTING_WINDOW) Slog.d(TAG, "Starting window removed " + win);
+            if (DEBUG_STARTING_WINDOW) Slog.d(TAG_WM, "Starting window removed " + win);
         }
 
         if (localLOGV || DEBUG_FOCUS || DEBUG_FOCUS_LIGHT && win==mCurrentFocus) Slog.v(
-                TAG, "Remove " + win + " client="
+                TAG_WM, "Remove " + win + " client="
                 + Integer.toHexString(System.identityHashCode(win.mClient.asBinder()))
                 + ", surfaceController=" + win.mWinAnimator.mSurfaceController + " Callers="
                 + Debug.getCallers(4));
@@ -2192,7 +2184,7 @@
         win.disposeInputChannel();
 
         if (DEBUG_APP_TRANSITIONS) Slog.v(
-                TAG, "Remove " + win + ": mSurfaceController=" + win.mWinAnimator.mSurfaceController
+                TAG_WM, "Remove " + win + ": mSurfaceController=" + win.mWinAnimator.mSurfaceController
                 + " mExiting=" + win.mExiting
                 + " isAnimating=" + win.mWinAnimator.isAnimating()
                 + " app-animation="
@@ -2213,7 +2205,7 @@
             if (appToken != null && appToken.mWillReplaceWindow) {
                 // This window is going to be replaced. We need to keep it around until the new one
                 // gets added, then we will get rid of this one.
-                if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Preserving " + win + " until the new one is "
+                if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Preserving " + win + " until the new one is "
                         + "added");
                 win.mExiting = true;
                 appToken.mReplacingRemoveRequested = true;
@@ -2225,7 +2217,7 @@
             wasVisible = win.isWinVisibleLw();
 
             if (wasVisible && appToken != null && appToken.appDied) {
-                if (DEBUG_ADD_REMOVE) Slog.v(TAG,
+                if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
                         "Not removing " + win + " because app died while it's visible");
 
                 win.mAppDied = true;
@@ -2300,7 +2292,7 @@
 
         for (int i=win.mChildWindows.size()-1; i>=0; i--) {
             WindowState cwin = win.mChildWindows.get(i);
-            Slog.w(TAG, "Force-removing child win " + cwin + " from container "
+            Slog.w(TAG_WM, "Force-removing child win " + cwin + " from container "
                     + win);
             removeWindowInnerLocked(cwin);
         }
@@ -2314,13 +2306,13 @@
         if (false) {
             RuntimeException e = new RuntimeException("here");
             e.fillInStackTrace();
-            Slog.w(TAG, "Removing window " + win, e);
+            Slog.w(TAG_WM, "Removing window " + win, e);
         }
 
         mPolicy.removeWindowLw(win);
         win.removeLocked();
 
-        if (DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win);
+        if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "removeWindowInnerLocked: " + win);
         mWindowMap.remove(win.mClient.asBinder());
         if (win.mAppOp != AppOpsManager.OP_NONE) {
             mAppOps.finishOp(win.mAppOp, win.getOwningUid(), win.getOwningPackage());
@@ -2329,7 +2321,7 @@
         mPendingRemove.remove(win);
         mResizingWindows.remove(win);
         mWindowsChanged = true;
-        if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
+        if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Final remove of window: " + win);
 
         if (mInputMethodWindow == win) {
             mInputMethodWindow = null;
@@ -2339,13 +2331,13 @@
 
         final WindowToken token = win.mToken;
         final AppWindowToken atoken = win.mAppToken;
-        if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + win + " from " + token);
+        if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Removing " + win + " from " + token);
         token.windows.remove(win);
         if (atoken != null) {
             atoken.allAppWindows.remove(win);
         }
         if (localLOGV) Slog.v(
-                TAG, "**** Removing window " + win + ": count="
+                TAG_WM, "**** Removing window " + win + ": count="
                 + token.windows.size());
         if (token.windows.size() == 0) {
             if (!token.explicit) {
@@ -2357,13 +2349,13 @@
 
         if (atoken != null) {
             if (atoken.startingWindow == win) {
-                if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Notify removed startingWindow " + win);
+                if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Notify removed startingWindow " + win);
                 scheduleRemoveStartingWindowLocked(atoken);
             } else
             if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
                 // If this is the last window and we had requested a starting
                 // transition window, well there is no point now.
-                if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling last startingWindow");
+                if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingWindow");
                 atoken.startingData = null;
             } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
                 // If this is the last window except for a starting transition
@@ -2419,18 +2411,18 @@
     static void logSurface(WindowState w, String msg, RuntimeException where) {
         String str = "  SURFACE " + msg + ": " + w;
         if (where != null) {
-            Slog.i(TAG, str, where);
+            Slog.i(TAG_WM, str, where);
         } else {
-            Slog.i(TAG, str);
+            Slog.i(TAG_WM, str);
         }
     }
 
     static void logSurface(SurfaceControl s, String title, String msg, RuntimeException where) {
         String str = "  SURFACE " + s + ": " + msg + " / " + title;
         if (where != null) {
-            Slog.i(TAG, str, where);
+            Slog.i(TAG_WM, str, where);
         } else {
-            Slog.i(TAG, str);
+            Slog.i(TAG_WM, str);
         }
     }
 
@@ -2542,26 +2534,32 @@
                 win.mAttrs.height = bottom - top;
                 win.setWindowScale(win.mRequestedWidth, win.mRequestedHeight);
 
-                if (SHOW_TRANSACTIONS) {
-                    Slog.i(TAG, ">>> OPEN TRANSACTION repositionChild");
-                }
+                if (win.mHasSurface) {
+                    if (SHOW_TRANSACTIONS) {
+                        Slog.i(TAG_WM, ">>> OPEN TRANSACTION repositionChild");
+                    }
 
-                SurfaceControl.openTransaction();
+                    SurfaceControl.openTransaction();
 
-                win.applyGravityAndUpdateFrame();
-                win.mWinAnimator.computeShownFrameLocked();
+                    try {
 
-                win.mWinAnimator.setSurfaceBoundariesLocked(false);
+                        win.applyGravityAndUpdateFrame();
+                        win.mWinAnimator.computeShownFrameLocked();
 
-                if (deferTransactionUntilFrame > 0) {
-                    win.mWinAnimator.mSurfaceController.deferTransactionUntil(
-                            win.mAttachedWindow.mWinAnimator.mSurfaceController.getHandle(),
-                            deferTransactionUntilFrame);
-                }
+                        win.mWinAnimator.setSurfaceBoundariesLocked(false);
 
-                SurfaceControl.closeTransaction();
-                if (SHOW_TRANSACTIONS) {
-                    Slog.i(TAG, "<<< CLOSE TRANSACTION repositionChild");
+                        if (deferTransactionUntilFrame > 0) {
+                            win.mWinAnimator.mSurfaceController.deferTransactionUntil(
+                                    win.mAttachedWindow.mWinAnimator.mSurfaceController.getHandle(),
+                                    deferTransactionUntilFrame);
+                        }
+
+                    } finally {
+                        SurfaceControl.closeTransaction();
+                        if (SHOW_TRANSACTIONS) {
+                            Slog.i(TAG_WM, "<<< CLOSE TRANSACTION repositionChild");
+                        }
+                    }
                 }
 
                 outFrame = win.mCompatFrame;
@@ -2633,7 +2631,7 @@
                 }
             }
 
-            if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": viewVisibility=" + viewVisibility
+            if (DEBUG_LAYOUT) Slog.v(TAG_WM, "Relayout " + win + ": viewVisibility=" + viewVisibility
                     + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs);
             winAnimator.mSurfaceDestroyDeferred = (flags & RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
             win.mEnforceSizeCompat =
@@ -2662,7 +2660,7 @@
             if (DEBUG_SCREEN_ON) {
                 RuntimeException stack = new RuntimeException();
                 stack.fillInStackTrace();
-                Slog.i(TAG, "Relayout " + win + ": oldVis=" + oldVisibility
+                Slog.i(TAG_WM, "Relayout " + win + ": oldVis=" + oldVisibility
                         + " newVis=" + viewVisibility, stack);
             }
             if (viewVisibility == View.VISIBLE &&
@@ -2674,7 +2672,7 @@
                 } catch (Exception e) {
                     mInputMonitor.updateInputWindowsLw(true /*force*/);
 
-                    Slog.w(TAG, "Exception thrown when creating surface for client "
+                    Slog.w(TAG_WM, "Exception thrown when creating surface for client "
                              + client + " (" + win.mAttrs.getTitle() + ")",
                              e);
                     Binder.restoreCallingIdentity(origId);
@@ -2693,7 +2691,7 @@
                 winAnimator.mEnteringAnimation = false;
                 if (winAnimator.mSurfaceController != null &&
                         winAnimator.mSurfaceController.hasSurface()) {
-                    if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
+                    if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Relayout invis " + win
                             + ": mExiting=" + win.mExiting);
                     // If we are using a saved surface to do enter animation, just let the
                     // animation run and don't destroy the surface. This could happen when
@@ -2713,7 +2711,7 @@
                 }
 
                 outSurface.release();
-                if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
+                if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Releasing surface in: " + win);
             }
 
             if (focusMayChange) {
@@ -2765,7 +2763,7 @@
             outStableInsets.set(win.mStableInsets);
             outOutsets.set(win.mOutsets);
             if (localLOGV) Slog.v(
-                TAG, "Relayout given client " + client.asBinder()
+                TAG_WM, "Relayout given client " + client.asBinder()
                 + ", requestedWidth=" + requestedWidth
                 + ", requestedHeight=" + requestedHeight
                 + ", viewVisibility=" + viewVisibility
@@ -2773,14 +2771,14 @@
                 + ", surface=" + outSurface);
 
             if (localLOGV || DEBUG_FOCUS) Slog.v(
-                TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
+                TAG_WM, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
 
             result |= mInTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0;
 
             mInputMonitor.updateInputWindowsLw(true /*force*/);
 
             if (DEBUG_LAYOUT) {
-                Slog.v(TAG, "Relayout complete " + win + ": outFrame=" + outFrame.toShortString());
+                Slog.v(TAG_WM, "Relayout complete " + win + ": outFrame=" + outFrame.toShortString());
             }
         }
 
@@ -2816,9 +2814,7 @@
             if (mInputMethodWindow == win) {
                 mInputMethodWindow = null;
             }
-            if (!win.shouldSaveSurface()) {
-                winAnimator.destroySurfaceLocked();
-            }
+            win.destroyOrSaveSurface();
         }
         //TODO (multidisplay): Magnification is supported only for the default
         if (mAccessibilityController != null
@@ -2836,7 +2832,7 @@
         WindowSurfaceController surfaceController = winAnimator.createSurfaceLocked();
         if (surfaceController != null) {
             surfaceController.getSurface(outSurface);
-            if (SHOW_TRANSACTIONS) Slog.i(TAG, "  OUT SURFACE " + outSurface + ": copied");
+            if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, "  OUT SURFACE " + outSurface + ": copied");
         } else {
             // For some reason there isn't a surface.  Clear the
             // caller's object so they see the same state.
@@ -2932,7 +2928,7 @@
         try {
             synchronized (mWindowMap) {
                 WindowState win = windowForClientLocked(session, client, false);
-                if (DEBUG_ADD_REMOVE) Slog.d(TAG, "finishDrawingWindow: " + win + " mDrawState="
+                if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "finishDrawingWindow: " + win + " mDrawState="
                         + (win != null ? win.mWinAnimator.drawStateToString() : "null"));
                 if (win != null && win.mWinAnimator.finishDrawingLocked()) {
                     if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
@@ -2958,7 +2954,7 @@
             DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
             final int width = displayInfo.appWidth;
             final int height = displayInfo.appHeight;
-            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
+            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG_WM,
                     "applyAnimation: atoken=" + atoken);
 
             // Determine the visible rect to calculate the thumbnail clip
@@ -2994,7 +2990,7 @@
                 // screen gets the enter animation. Both appear in the mOpeningApps set.
                 enter = false;
             }
-            if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "Loading animation for app transition."
+            if (DEBUG_APP_TRANSITIONS) Slog.d(TAG_WM, "Loading animation for app transition."
                     + " transit=" + AppTransition.appTransitionToString(transit) + " enter=" + enter
                     + " frame=" + frame + " insets=" + insets + " surfaceInsets=" + surfaceInsets);
             Animation a = mAppTransition.loadAnimation(lp, transit, enter,
@@ -3007,7 +3003,7 @@
                         e = new RuntimeException();
                         e.fillInStackTrace();
                     }
-                    Slog.v(TAG, "Loaded animation " + a + " for " + atoken, e);
+                    Slog.v(TAG_WM, "Loaded animation " + a + " for " + atoken, e);
                 }
                 final int containingWidth = frame.width();
                 final int containingHeight = frame.height();
@@ -3029,7 +3025,7 @@
         synchronized (mWindowMap) {
             int t = tasks.size() - 1;
             if (t < 0) {
-                Slog.w(TAG, "validateAppTokens: empty task list");
+                Slog.w(TAG_WM, "validateAppTokens: empty task list");
                 return;
             }
 
@@ -3038,7 +3034,7 @@
             Task targetTask = mTaskIdToTask.get(taskId);
             DisplayContent displayContent = targetTask.getDisplayContent();
             if (displayContent == null) {
-                Slog.w(TAG, "validateAppTokens: no Display for taskId=" + taskId);
+                Slog.w(TAG_WM, "validateAppTokens: no Display for taskId=" + taskId);
                 return;
             }
 
@@ -3052,7 +3048,7 @@
                 DisplayContent lastDisplayContent = displayContent;
                 displayContent = mTaskIdToTask.get(taskId).getDisplayContent();
                 if (displayContent != lastDisplayContent) {
-                    Slog.w(TAG, "validateAppTokens: displayContent changed in TaskGroup list!");
+                    Slog.w(TAG_WM, "validateAppTokens: displayContent changed in TaskGroup list!");
                     return;
                 }
 
@@ -3078,9 +3074,9 @@
             }
 
             if (taskNdx >= 0 || t >= 0) {
-                Slog.w(TAG, "validateAppTokens: Mismatch! ActivityManager=" + tasks);
-                Slog.w(TAG, "validateAppTokens: Mismatch! WindowManager=" + localTasks);
-                Slog.w(TAG, "validateAppTokens: Mismatch! Callers=" + Debug.getCallers(4));
+                Slog.w(TAG_WM, "validateAppTokens: Mismatch! ActivityManager=" + tasks);
+                Slog.w(TAG_WM, "validateAppTokens: Mismatch! WindowManager=" + localTasks);
+                Slog.w(TAG_WM, "validateAppTokens: Mismatch! Callers=" + Debug.getCallers(4));
             }
         }
     }
@@ -3103,7 +3099,7 @@
                 + Binder.getCallingPid()
                 + ", uid=" + Binder.getCallingUid()
                 + " requires " + permission;
-        Slog.w(TAG, msg);
+        Slog.w(TAG_WM, msg);
         return false;
     }
 
@@ -3129,7 +3125,7 @@
         synchronized(mWindowMap) {
             WindowToken wtoken = mTokenMap.get(token);
             if (wtoken != null) {
-                Slog.w(TAG, "Attempted to add existing input method token: " + token);
+                Slog.w(TAG_WM, "Attempted to add existing input method token: " + token);
                 return;
             }
             wtoken = new WindowToken(this, token, type, true);
@@ -3199,7 +3195,7 @@
 
                 mInputMonitor.updateInputWindowsLw(true /*force*/);
             } else {
-                Slog.w(TAG, "Attempted to remove non-existing token: " + token);
+                Slog.w(TAG_WM, "Attempted to remove non-existing token: " + token);
             }
         }
         Binder.restoreCallingIdentity(origId);
@@ -3207,7 +3203,7 @@
 
     private Task createTaskLocked(int taskId, int stackId, int userId, AppWindowToken atoken,
             Rect bounds, Configuration config) {
-        if (DEBUG_STACK) Slog.i(TAG, "createTaskLocked: taskId=" + taskId + " stackId=" + stackId
+        if (DEBUG_STACK) Slog.i(TAG_WM, "createTaskLocked: taskId=" + taskId + " stackId=" + stackId
                 + " atoken=" + atoken + " bounds=" + bounds);
         final TaskStack stack = mStackIdToStack.get(stackId);
         if (stack == null) {
@@ -3240,14 +3236,14 @@
         try {
             inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
         } catch (RemoteException ex) {
-            Slog.w(TAG, "Could not get dispatching timeout.", ex);
+            Slog.w(TAG_WM, "Could not get dispatching timeout.", ex);
             inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
         }
 
         synchronized(mWindowMap) {
             AppWindowToken atoken = findAppWindowToken(token.asBinder());
             if (atoken != null) {
-                Slog.w(TAG, "Attempted to add existing app token: " + token);
+                Slog.w(TAG_WM, "Attempted to add existing app token: " + token);
                 return;
             }
             atoken = new AppWindowToken(this, token, voiceInteraction);
@@ -3259,7 +3255,7 @@
                     (ActivityInfo.CONFIG_SCREEN_SIZE | ActivityInfo.CONFIG_ORIENTATION)) != 0;
             atoken.mLaunchTaskBehind = launchTaskBehind;
             atoken.mCropWindowsToStack = cropWindowsToStack;
-            if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + atoken
+            if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "addAppToken: " + atoken
                     + " to stack=" + stackId + " task=" + taskId + " at " + addPos);
 
             Task task = mTaskIdToTask.get(taskId);
@@ -3287,7 +3283,7 @@
         synchronized(mWindowMap) {
             final AppWindowToken atoken = findAppWindowToken(token);
             if (atoken == null) {
-                Slog.w(TAG, "Attempted to set task id of non-existing app token: " + token);
+                Slog.w(TAG_WM, "Attempted to set task id of non-existing app token: " + token);
                 return;
             }
             final Task oldTask = atoken.mTask;
@@ -3305,7 +3301,7 @@
     public int getOrientationLocked() {
         if (mDisplayFrozen) {
             if (mLastWindowForcedOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
-                if (DEBUG_ORIENTATION) Slog.v(TAG,
+                if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
                         "Display is frozen, return " + mLastWindowForcedOrientation);
                 // If the display is frozen, some activities may be in the middle
                 // of restarting, and thus have removed their old window.  If the
@@ -3332,7 +3328,7 @@
                     continue;
                 }
 
-                if (DEBUG_ORIENTATION) Slog.v(TAG, win + " forcing orientation to " + req);
+                if (DEBUG_ORIENTATION) Slog.v(TAG_WM, win + " forcing orientation to " + req);
                 if (mPolicy.isKeyguardHostWindow(win.mAttrs)) {
                     mLastKeyguardForcedOrientation = req;
                 }
@@ -3352,11 +3348,11 @@
                     if (req == SCREEN_ORIENTATION_BEHIND) {
                         req = mLastKeyguardForcedOrientation;
                     }
-                    if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + appShowWhenLocked
+                    if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Done at " + appShowWhenLocked
                             + " -- show when locked, return " + req);
                     return req;
                 }
-                if (DEBUG_ORIENTATION) Slog.v(TAG,
+                if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
                         "No one is requesting an orientation when the screen is locked");
                 return mLastKeyguardForcedOrientation;
             }
@@ -3386,12 +3382,12 @@
             for (int tokenNdx = firstToken; tokenNdx >= 0; --tokenNdx) {
                 final AppWindowToken atoken = tokens.get(tokenNdx);
 
-                if (DEBUG_APP_ORIENTATION) Slog.v(TAG, "Checking app orientation: " + atoken);
+                if (DEBUG_APP_ORIENTATION) Slog.v(TAG_WM, "Checking app orientation: " + atoken);
 
                 // if we're about to tear down this window and not seek for
                 // the behind activity, don't use it for orientation
                 if (!findingBehind && !atoken.hidden && atoken.hiddenRequested) {
-                    if (DEBUG_ORIENTATION) Slog.v(TAG,
+                    if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
                             "Skipping " + atoken + " -- going to hide");
                     continue;
                 }
@@ -3401,7 +3397,7 @@
                     // explicitly say to use the orientation behind it, and the last app was
                     // full screen, then we'll stick with the user's orientation.
                     if (lastOrientation != SCREEN_ORIENTATION_BEHIND && lastFullscreen) {
-                        if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
+                        if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Done at " + atoken
                                 + " -- end of group, return " + lastOrientation);
                         return lastOrientation;
                     }
@@ -3409,7 +3405,7 @@
 
                 // We ignore any hidden applications on the top.
                 if (atoken.hiddenRequested) {
-                    if (DEBUG_ORIENTATION) Slog.v(TAG,
+                    if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
                             "Skipping " + atoken + " -- hidden on top");
                     continue;
                 }
@@ -3425,20 +3421,20 @@
                 // orientation it has and ignores whatever is under it.
                 lastFullscreen = atoken.appFullscreen;
                 if (lastFullscreen && or != SCREEN_ORIENTATION_BEHIND) {
-                    if (DEBUG_ORIENTATION) Slog.v(TAG,
+                    if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
                             "Done at " + atoken + " -- full screen, return " + or);
                     return or;
                 }
                 // If this application has requested an explicit orientation, then use it.
                 if (or != SCREEN_ORIENTATION_UNSPECIFIED && or != SCREEN_ORIENTATION_BEHIND) {
-                    if (DEBUG_ORIENTATION) Slog.v(TAG,
+                    if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
                             "Done at " + atoken + " -- explicitly set, return " + or);
                     return or;
                 }
                 findingBehind |= (or == SCREEN_ORIENTATION_BEHIND);
             }
         }
-        if (DEBUG_ORIENTATION) Slog.v(TAG,
+        if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
                 "No app is requesting an orientation, return " + mForcedAppOrientation);
         // The next app has not been requested to be visible, so we keep the current orientation
         // to prevent freezing/unfreezing the display too early.
@@ -3569,7 +3565,7 @@
         synchronized(mWindowMap) {
             AppWindowToken atoken = findAppWindowToken(token.asBinder());
             if (atoken == null) {
-                Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
+                Slog.w(TAG_WM, "Attempted to set orientation of non-existing app token: " + token);
                 return;
             }
 
@@ -3609,14 +3605,14 @@
         synchronized(mWindowMap) {
             final AppWindowToken newFocus;
             if (token == null) {
-                if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
+                if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Clearing focused app, was " + mFocusedApp);
                 newFocus = null;
             } else {
                 newFocus = findAppWindowToken(token);
                 if (newFocus == null) {
-                    Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
+                    Slog.w(TAG_WM, "Attempted to set focus to non-existing app token: " + token);
                 }
-                if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Set focused app to: " + newFocus
+                if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Set focused app to: " + newFocus
                         + " old focus=" + mFocusedApp + " moveFocusNow=" + moveFocusNow);
             }
 
@@ -3776,7 +3772,7 @@
         }
 
         synchronized(mWindowMap) {
-            if (DEBUG_APP_TRANSITIONS) Slog.w(TAG, "Execute app transition: " + mAppTransition
+            if (DEBUG_APP_TRANSITIONS) Slog.w(TAG_WM, "Execute app transition: " + mAppTransition
                     + " Callers=" + Debug.getCallers(5));
             if (mAppTransition.isTransitionSet()) {
                 mAppTransition.setReady();
@@ -3802,12 +3798,12 @@
 
         synchronized(mWindowMap) {
             if (DEBUG_STARTING_WINDOW) Slog.v(
-                    TAG, "setAppStartingWindow: token=" + token + " pkg=" + pkg
+                    TAG_WM, "setAppStartingWindow: token=" + token + " pkg=" + pkg
                     + " transferFrom=" + transferFrom);
 
             AppWindowToken wtoken = findAppWindowToken(token);
             if (wtoken == null) {
-                Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
+                Slog.w(TAG_WM, "Attempted to set icon of non-existing app token: " + token);
                 return;
             }
 
@@ -3836,7 +3832,7 @@
             // show a starting window -- the current effect (a full-screen
             // opaque starting window that fades away to the real contents
             // when it is ready) does not work for this.
-            if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Checking theme of starting window: 0x"
+            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Checking theme of starting window: 0x"
                     + Integer.toHexString(theme));
             if (theme != 0) {
                 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
@@ -3854,7 +3850,7 @@
                         com.android.internal.R.styleable.Window_windowShowWallpaper, false);
                 final boolean windowDisableStarting = ent.array.getBoolean(
                         com.android.internal.R.styleable.Window_windowDisablePreview, false);
-                if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Translucent=" + windowIsTranslucent
+                if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Translucent=" + windowIsTranslucent
                         + " Floating=" + windowIsFloating
                         + " ShowWallpaper=" + windowShowWallpaper);
                 if (windowIsTranslucent) {
@@ -3877,14 +3873,14 @@
                 }
             }
 
-            if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Creating StartingData");
+            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating StartingData");
             wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
                     labelRes, icon, logo, windowFlags);
             Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
             // Note: we really want to do sendMessageAtFrontOfQueue() because we
             // want to process the message ASAP, before any other queued
             // messages.
-            if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Enqueueing ADD_STARTING");
+            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Enqueueing ADD_STARTING");
             mH.sendMessageAtFrontOfQueue(m);
         }
     }
@@ -3903,7 +3899,7 @@
             // letting windows get shown immediately without any more transitions.
             mSkipAppTransitionAnimation = true;
 
-            if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
+            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
                     "Moving existing starting " + startingWindow + " from " + ttoken
                             + " to " + wtoken);
             final long origId = Binder.clearCallingIdentity();
@@ -3924,11 +3920,11 @@
             startingWindow.mAppToken = wtoken;
 
             if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) {
-                Slog.v(TAG, "Removing starting window: " + startingWindow);
+                Slog.v(TAG_WM, "Removing starting window: " + startingWindow);
             }
             startingWindow.getWindowList().remove(startingWindow);
             mWindowsChanged = true;
-            if (DEBUG_ADD_REMOVE) Slog.v(TAG,
+            if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
                     "Removing starting " + startingWindow + " from " + ttoken);
             ttoken.windows.remove(startingWindow);
             ttoken.allAppWindows.remove(startingWindow);
@@ -3966,7 +3962,7 @@
         } else if (ttoken.startingData != null) {
             // The previous app was getting ready to show a
             // starting window, but hasn't yet done so.  Steal it!
-            if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Moving pending starting from " + ttoken
+            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Moving pending starting from " + ttoken
                     + " to " + wtoken);
             wtoken.startingData = ttoken.startingData;
             ttoken.startingData = null;
@@ -4049,7 +4045,7 @@
                 (visible && wtoken.mWillReplaceWindow)) {
             boolean changed = false;
             if (DEBUG_APP_TRANSITIONS) Slog.v(
-                TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
+                TAG_WM, "Changing app " + wtoken + " hidden=" + wtoken.hidden
                 + " performLayout=" + performLayout);
 
             boolean runningAppAnimation = false;
@@ -4077,7 +4073,7 @@
                     continue;
                 }
 
-                //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
+                //Slog.i(TAG_WM, "Window " + win + ": vis=" + win.isVisible());
                 //win.dump("  ");
                 if (visible) {
                     if (!win.isVisibleNow()) {
@@ -4123,7 +4119,7 @@
                  }
             }
 
-            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
+            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "setTokenVisibilityLocked: " + wtoken
                       + ": hidden=" + wtoken.hidden + " hiddenRequested="
                       + wtoken.hiddenRequested);
 
@@ -4172,11 +4168,11 @@
         synchronized(mWindowMap) {
             wtoken = findAppWindowToken(token);
             if (wtoken == null) {
-                Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
+                Slog.w(TAG_WM, "Attempted to set visibility of non-existing app token: " + token);
                 return;
             }
 
-            if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) Slog.v(TAG, "setAppVisibility(" +
+            if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) Slog.v(TAG_WM, "setAppVisibility(" +
                     token + ", visible=" + visible + "): " + mAppTransition +
                     " hidden=" + wtoken.hidden + " hiddenRequested=" +
                     wtoken.hiddenRequested + " Callers=" + Debug.getCallers(6));
@@ -4204,7 +4200,7 @@
                 if (!wtoken.mAppAnimator.usingTransferredAnimation &&
                         (!wtoken.startingDisplayed || mSkipAppTransitionAnimation)) {
                     if (DEBUG_APP_TRANSITIONS) Slog.v(
-                            TAG, "Setting dummy animation on: " + wtoken);
+                            TAG_WM, "Setting dummy animation on: " + wtoken);
                     wtoken.mAppAnimator.setDummyAnimation();
                 }
                 wtoken.inPendingTransaction = true;
@@ -4243,7 +4239,7 @@
                     if (win != null) {
                         final AppWindowToken focusedToken = win.mAppToken;
                         if (focusedToken != null) {
-                            if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "TRANSIT_TASK_OPEN_BEHIND, " +
+                            if (DEBUG_APP_TRANSITIONS) Slog.d(TAG_WM, "TRANSIT_TASK_OPEN_BEHIND, " +
                                     " adding " + focusedToken + " to mOpeningApps");
                             // Force animation to be loaded.
                             focusedToken.hidden = true;
@@ -4266,7 +4262,7 @@
     void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
             boolean unfreezeSurfaceNow, boolean force) {
         if (wtoken.mAppAnimator.freezingScreen) {
-            if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
+            if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + wtoken
                     + " force=" + force);
             final int N = wtoken.allAppWindows.size();
             boolean unfrozeWindows = false;
@@ -4276,7 +4272,7 @@
                     w.mAppFreezing = false;
                     if (w.mHasSurface && !w.mOrientationChanging
                             && mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
-                        if (DEBUG_ORIENTATION) Slog.v(TAG, "set mOrientationChanging of " + w);
+                        if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "set mOrientationChanging of " + w);
                         w.mOrientationChanging = true;
                         mWindowPlacerLocked.mOrientationChangeComplete = false;
                     }
@@ -4286,7 +4282,7 @@
                 }
             }
             if (force || unfrozeWindows) {
-                if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
+                if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "No longer freezing: " + wtoken);
                 wtoken.mAppAnimator.freezingScreen = false;
                 wtoken.mAppAnimator.lastFreezeDuration = (int)(SystemClock.elapsedRealtime()
                         - mDisplayFreezeTime);
@@ -4309,7 +4305,7 @@
                 e = new RuntimeException();
                 e.fillInStackTrace();
             }
-            Slog.i(TAG, "Set freezing of " + wtoken.appToken
+            Slog.i(TAG_WM, "Set freezing of " + wtoken.appToken
                     + ": hidden=" + wtoken.hidden + " freezing="
                     + wtoken.mAppAnimator.freezingScreen, e);
         }
@@ -4341,13 +4337,13 @@
 
         synchronized(mWindowMap) {
             if (configChanges == 0 && okToDisplay()) {
-                if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
+                if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Skipping set freeze of " + token);
                 return;
             }
 
             AppWindowToken wtoken = findAppWindowToken(token);
             if (wtoken == null || wtoken.appToken == null) {
-                Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
+                Slog.w(TAG_WM, "Attempted to freeze screen with non-existing app token: " + wtoken);
                 return;
             }
             final long origId = Binder.clearCallingIdentity();
@@ -4369,7 +4365,7 @@
                 return;
             }
             final long origId = Binder.clearCallingIdentity();
-            if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
+            if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + token
                     + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.mAppAnimator.freezingScreen);
             unsetAppFreezingScreenLocked(wtoken, true, force);
             Binder.restoreCallingIdentity(origId);
@@ -4391,7 +4387,7 @@
         synchronized(mWindowMap) {
             WindowToken basewtoken = mTokenMap.remove(token);
             if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
-                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
+                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app token: " + wtoken);
                 delayed = setTokenVisibilityLocked(wtoken, null, false,
                         AppTransition.TRANSIT_UNSET, true, wtoken.voiceInteraction);
                 wtoken.inPendingTransaction = false;
@@ -4404,15 +4400,15 @@
                     delayed = true;
                 }
                 if (DEBUG_APP_TRANSITIONS) Slog.v(
-                        TAG, "Removing app " + wtoken + " delayed=" + delayed
+                        TAG_WM, "Removing app " + wtoken + " delayed=" + delayed
                         + " animation=" + wtoken.mAppAnimator.animation
                         + " animating=" + wtoken.mAppAnimator.animating);
-                if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "removeAppToken: "
+                if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM, "removeAppToken: "
                         + wtoken + " delayed=" + delayed + " Callers=" + Debug.getCallers(4));
                 final TaskStack stack = wtoken.mTask.mStack;
                 if (delayed && !wtoken.allAppWindows.isEmpty()) {
                     // set the token aside because it has an active animation to be finished
-                    if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
+                    if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM,
                             "removeAppToken make exiting: " + wtoken);
                     stack.mExitingAppTokens.add(wtoken);
                     wtoken.mIsExiting = true;
@@ -4431,13 +4427,13 @@
                 }
                 unsetAppFreezingScreenLocked(wtoken, true, true);
                 if (mFocusedApp == wtoken) {
-                    if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Removing focused app token:" + wtoken);
+                    if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Removing focused app token:" + wtoken);
                     mFocusedApp = null;
                     updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
                     mInputMonitor.setFocusedAppLw(null);
                 }
             } else {
-                Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
+                Slog.w(TAG_WM, "Attempted to remove non-existing app token: " + token);
             }
 
             if (!delayed && wtoken != null) {
@@ -4457,7 +4453,7 @@
             return;
         }
         if (wtoken != null && wtoken.startingWindow != null) {
-            if (DEBUG_STARTING_WINDOW) Slog.v(TAG, Debug.getCallers(1) +
+            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, Debug.getCallers(1) +
                     ": Schedule remove starting " + wtoken + (wtoken != null ?
                     " startingWindow=" + wtoken.startingWindow : ""));
             Message m = mH.obtainMessage(H.REMOVE_STARTING, wtoken);
@@ -4469,16 +4465,16 @@
         final int numStacks = mStackIdToStack.size();
         for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
             final TaskStack stack = mStackIdToStack.valueAt(stackNdx);
-            Slog.v(TAG, "  Stack #" + stack.mStackId + " tasks from bottom to top:");
+            Slog.v(TAG_WM, "  Stack #" + stack.mStackId + " tasks from bottom to top:");
             final ArrayList<Task> tasks = stack.getTasks();
             final int numTasks = tasks.size();
             for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
                 final Task task = tasks.get(taskNdx);
-                Slog.v(TAG, "    Task #" + task.mTaskId + " activities from bottom to top:");
+                Slog.v(TAG_WM, "    Task #" + task.mTaskId + " activities from bottom to top:");
                 AppTokenList tokens = task.mAppTokens;
                 final int numTokens = tokens.size();
                 for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
-                    Slog.v(TAG, "      activity #" + tokenNdx + ": " + tokens.get(tokenNdx).token);
+                    Slog.v(TAG_WM, "      activity #" + tokenNdx + ": " + tokens.get(tokenNdx).token);
                 }
             }
         }
@@ -4488,10 +4484,10 @@
         final int numDisplays = mDisplayContents.size();
         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
             final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
-            Slog.v(TAG, " Display #" + displayContent.getDisplayId());
+            Slog.v(TAG_WM, " Display #" + displayContent.getDisplayId());
             final WindowList windows = displayContent.getWindowList();
             for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
-                Slog.v(TAG, "  #" + winNdx + ": " + windows.get(winNdx));
+                Slog.v(TAG_WM, "  #" + winNdx + ": " + windows.get(winNdx));
             }
         }
     }
@@ -4504,21 +4500,21 @@
         for (int j=0; j<NCW; j++) {
             WindowState cwin = win.mChildWindows.get(j);
             if (!winAdded && cwin.mSubLayer >= 0) {
-                if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
+                if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Re-adding child window at "
                         + index + ": " + cwin);
                 win.mRebuilding = false;
                 windows.add(index, win);
                 index++;
                 winAdded = true;
             }
-            if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
+            if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Re-adding window at "
                     + index + ": " + cwin);
             cwin.mRebuilding = false;
             windows.add(index, cwin);
             index++;
         }
         if (!winAdded) {
-            if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
+            if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Re-adding window at "
                     + index + ": " + win);
             win.mRebuilding = false;
             windows.add(index, win);
@@ -4625,7 +4621,7 @@
             synchronized(mWindowMap) {
                 Task task = mTaskIdToTask.get(taskId);
                 if (task == null) {
-                    Slog.e(TAG, "moveTaskToBottom: taskId=" + taskId
+                    Slog.e(TAG_WM, "moveTaskToBottom: taskId=" + taskId
                             + " not found in mTaskIdToTask");
                     return;
                 }
@@ -4669,7 +4665,7 @@
                 if (displayContent != null) {
                     TaskStack stack = mStackIdToStack.get(stackId);
                     if (stack == null) {
-                        if (DEBUG_STACK) Slog.d(TAG, "attachStack: stackId=" + stackId);
+                        if (DEBUG_STACK) Slog.d(TAG_WM, "attachStack: stackId=" + stackId);
                         stack = new TaskStack(this, stackId);
                         mStackIdToStack.put(stackId, stack);
                     }
@@ -4725,7 +4721,7 @@
         synchronized (mWindowMap) {
             Task task = mTaskIdToTask.get(taskId);
             if (task == null) {
-                if (DEBUG_STACK) Slog.i(TAG, "removeTask: could not find taskId=" + taskId);
+                if (DEBUG_STACK) Slog.i(TAG_WM, "removeTask: could not find taskId=" + taskId);
                 return;
             }
             task.removeLocked();
@@ -4754,11 +4750,11 @@
 
     public void addTask(int taskId, int stackId, boolean toTop) {
         synchronized (mWindowMap) {
-            if (DEBUG_STACK) Slog.i(TAG, "addTask: adding taskId=" + taskId
+            if (DEBUG_STACK) Slog.i(TAG_WM, "addTask: adding taskId=" + taskId
                     + " to " + (toTop ? "top" : "bottom"));
             Task task = mTaskIdToTask.get(taskId);
             if (task == null) {
-                if (DEBUG_STACK) Slog.i(TAG, "addTask: could not find taskId=" + taskId);
+                if (DEBUG_STACK) Slog.i(TAG_WM, "addTask: could not find taskId=" + taskId);
                 return;
             }
             TaskStack stack = mStackIdToStack.get(stackId);
@@ -4771,16 +4767,16 @@
 
     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
         synchronized (mWindowMap) {
-            if (DEBUG_STACK) Slog.i(TAG, "moveTaskToStack: moving taskId=" + taskId
+            if (DEBUG_STACK) Slog.i(TAG_WM, "moveTaskToStack: moving taskId=" + taskId
                     + " to stackId=" + stackId + " at " + (toTop ? "top" : "bottom"));
             Task task = mTaskIdToTask.get(taskId);
             if (task == null) {
-                if (DEBUG_STACK) Slog.i(TAG, "moveTaskToStack: could not find taskId=" + taskId);
+                if (DEBUG_STACK) Slog.i(TAG_WM, "moveTaskToStack: could not find taskId=" + taskId);
                 return;
             }
             TaskStack stack = mStackIdToStack.get(stackId);
             if (stack == null) {
-                if (DEBUG_STACK) Slog.i(TAG, "moveTaskToStack: could not find stackId=" + stackId);
+                if (DEBUG_STACK) Slog.i(TAG_WM, "moveTaskToStack: could not find stackId=" + stackId);
                 return;
             }
             task.moveTaskToStack(stack, toTop);
@@ -4805,7 +4801,7 @@
         synchronized (mWindowMap) {
             Task task = mTaskIdToTask.get(taskId);
             if (task == null) {
-                if (DEBUG_STACK) Slog.i(TAG, "scheduleShowToast: could not find taskId=" + taskId);
+                if (DEBUG_STACK) Slog.i(TAG_WM, "scheduleShowToast: could not find taskId=" + taskId);
                 return;
             }
             task.setShowNonResizeableDockToast();
@@ -4851,17 +4847,17 @@
     public void positionTaskInStack(int taskId, int stackId, int position, Rect bounds,
             Configuration config) {
         synchronized (mWindowMap) {
-            if (DEBUG_STACK) Slog.i(TAG, "positionTaskInStack: positioning taskId=" + taskId
+            if (DEBUG_STACK) Slog.i(TAG_WM, "positionTaskInStack: positioning taskId=" + taskId
                     + " in stackId=" + stackId + " at " + position);
             Task task = mTaskIdToTask.get(taskId);
             if (task == null) {
-                if (DEBUG_STACK) Slog.i(TAG,
+                if (DEBUG_STACK) Slog.i(TAG_WM,
                         "positionTaskInStack: could not find taskId=" + taskId);
                 return;
             }
             TaskStack stack = mStackIdToStack.get(stackId);
             if (stack == null) {
-                if (DEBUG_STACK) Slog.i(TAG,
+                if (DEBUG_STACK) Slog.i(TAG_WM,
                         "positionTaskInStack: could not find stackId=" + stackId);
                 return;
             }
@@ -5002,7 +4998,7 @@
         // If this isn't coming from the system then don't allow disabling the lockscreen
         // to bypass security.
         if (Binder.getCallingUid() != Process.SYSTEM_UID && isKeyguardSecure()) {
-            Log.d(TAG, "current mode is SecurityMode, ignore hide keyguard");
+            Log.d(TAG_WM, "current mode is SecurityMode, ignore hide keyguard");
             return;
         }
 
@@ -5093,7 +5089,7 @@
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires DISABLE_KEYGUARD permission");
         }
-        if (DEBUG_KEYGUARD) Slog.d(TAG, "keyguardGoingAway: disableWinAnim="
+        if (DEBUG_KEYGUARD) Slog.d(TAG_WM, "keyguardGoingAway: disableWinAnim="
                 + disableWindowAnimations + " kgToNotifShade=" + keyguardGoingToNotificationShade);
         synchronized (mWindowMap) {
             mAnimator.mKeyguardGoingAway = true;
@@ -5104,14 +5100,14 @@
     }
 
     public void keyguardWaitingForActivityDrawn() {
-        if (DEBUG_KEYGUARD) Slog.d(TAG, "keyguardWaitingForActivityDrawn");
+        if (DEBUG_KEYGUARD) Slog.d(TAG_WM, "keyguardWaitingForActivityDrawn");
         synchronized (mWindowMap) {
             mKeyguardWaitingForActivityDrawn = true;
         }
     }
 
     public void notifyActivityDrawnForKeyguard() {
-        if (DEBUG_KEYGUARD) Slog.d(TAG, "notifyActivityDrawnForKeyguard: waiting="
+        if (DEBUG_KEYGUARD) Slog.d(TAG_WM, "notifyActivityDrawnForKeyguard: waiting="
                 + mKeyguardWaitingForActivityDrawn + " Callers=" + Debug.getCallers(5));
         synchronized (mWindowMap) {
             if (mKeyguardWaitingForActivityDrawn) {
@@ -5262,6 +5258,12 @@
 
     // Called by window manager policy. Not exposed externally.
     @Override
+    public void lockDeviceNow() {
+        lockNow(null);
+    }
+
+    // Called by window manager policy. Not exposed externally.
+    @Override
     public int getCameraLensCoverState() {
         int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY,
                 InputManagerService.SW_CAMERA_LENS_COVER);
@@ -5333,7 +5335,7 @@
             if (DEBUG_BOOT) {
                 RuntimeException here = new RuntimeException("here");
                 here.fillInStackTrace();
-                Slog.i(TAG, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled
+                Slog.i(TAG_WM, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled
                         + " mForceDisplayEnabled=" + mForceDisplayEnabled
                         + " mShowingBootMessages=" + mShowingBootMessages
                         + " mSystemBooted=" + mSystemBooted, here);
@@ -5364,7 +5366,7 @@
         if (DEBUG_BOOT) {
             RuntimeException here = new RuntimeException("here");
             here.fillInStackTrace();
-            Slog.i(TAG, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled
+            Slog.i(TAG_WM, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled
                     + " mForceDisplayEnabled=" + mForceDisplayEnabled
                     + " mShowingBootMessages=" + mShowingBootMessages
                     + " mSystemBooted=" + mSystemBooted, here);
@@ -5383,7 +5385,7 @@
             if (mDisplayEnabled) {
                 return;
             }
-            Slog.w(TAG, "***** BOOT TIMEOUT: forcing display enabled");
+            Slog.w(TAG_WM, "***** BOOT TIMEOUT: forcing display enabled");
             mForceDisplayEnabled = true;
         }
         performEnableScreen();
@@ -5422,7 +5424,7 @@
         }
 
         if (DEBUG_SCREEN_ON || DEBUG_BOOT) {
-            Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
+            Slog.i(TAG_WM, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
                     + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
                     + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled
                     + " haveKeyguard=" + haveKeyguard);
@@ -5447,7 +5449,7 @@
 
     public void performEnableScreen() {
         synchronized(mWindowMap) {
-            if (DEBUG_BOOT) Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
+            if (DEBUG_BOOT) Slog.i(TAG_WM, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
                     + " mForceDisplayEnabled=" + mForceDisplayEnabled
                     + " mShowingBootMessages=" + mShowingBootMessages
                     + " mSystemBooted=" + mSystemBooted
@@ -5471,7 +5473,7 @@
                 try {
                     IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
                     if (surfaceFlinger != null) {
-                        //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
+                        //Slog.i(TAG_WM, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
                         Parcel data = Parcel.obtain();
                         data.writeInterfaceToken("android.ui.ISurfaceComposer");
                         surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
@@ -5479,20 +5481,20 @@
                         data.recycle();
                     }
                 } catch (RemoteException ex) {
-                    Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
+                    Slog.e(TAG_WM, "Boot completed: SurfaceFlinger is dead!");
                 }
                 mBootAnimationStopped = true;
             }
 
             if (!mForceDisplayEnabled && !checkBootAnimationCompleteLocked()) {
-                if (DEBUG_BOOT) Slog.i(TAG, "performEnableScreen: Waiting for anim complete");
+                if (DEBUG_BOOT) Slog.i(TAG_WM, "performEnableScreen: Waiting for anim complete");
                 return;
             }
 
             EventLog.writeEvent(EventLogTags.WM_BOOT_ANIMATION_DONE, SystemClock.uptimeMillis());
             Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
             mDisplayEnabled = true;
-            if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!");
+            if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG_WM, "******************** ENABLING SCREEN!");
 
             // Enable input dispatch.
             mInputMonitor.setEventDispatchingLw(mEventDispatchingEnabled);
@@ -5514,10 +5516,10 @@
             mH.removeMessages(H.CHECK_IF_BOOT_ANIMATION_FINISHED);
             mH.sendEmptyMessageDelayed(H.CHECK_IF_BOOT_ANIMATION_FINISHED,
                     BOOT_ANIMATION_POLL_INTERVAL);
-            if (DEBUG_BOOT) Slog.i(TAG, "checkBootAnimationComplete: Waiting for anim complete");
+            if (DEBUG_BOOT) Slog.i(TAG_WM, "checkBootAnimationComplete: Waiting for anim complete");
             return false;
         }
-        if (DEBUG_BOOT) Slog.i(TAG, "checkBootAnimationComplete: Animation complete!");
+        if (DEBUG_BOOT) Slog.i(TAG_WM, "checkBootAnimationComplete: Animation complete!");
         return true;
     }
 
@@ -5527,7 +5529,7 @@
             if (DEBUG_BOOT) {
                 RuntimeException here = new RuntimeException("here");
                 here.fillInStackTrace();
-                Slog.i(TAG, "showBootMessage: msg=" + msg + " always=" + always
+                Slog.i(TAG_WM, "showBootMessage: msg=" + msg + " always=" + always
                         + " mAllowBootMessages=" + mAllowBootMessages
                         + " mShowingBootMessages=" + mShowingBootMessages
                         + " mSystemBooted=" + mSystemBooted, here);
@@ -5556,7 +5558,7 @@
         if (DEBUG_BOOT) {
             RuntimeException here = new RuntimeException("here");
             here.fillInStackTrace();
-            Slog.i(TAG, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled
+            Slog.i(TAG_WM, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled
                     + " mForceDisplayEnabled=" + mForceDisplayEnabled
                     + " mShowingBootMessages=" + mShowingBootMessages
                     + " mSystemBooted=" + mSystemBooted, here);
@@ -5607,7 +5609,7 @@
     public void showCircularMask(boolean visible) {
         synchronized(mWindowMap) {
 
-            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
                     ">>> OPEN TRANSACTION showCircularMask(visible=" + visible + ")");
             SurfaceControl.openTransaction();
             try {
@@ -5633,7 +5635,7 @@
                 }
             } finally {
                 SurfaceControl.closeTransaction();
-                if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+                if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
                         "<<< CLOSE TRANSACTION showCircularMask(visible=" + visible + ")");
             }
         }
@@ -5642,7 +5644,7 @@
     public void showEmulatorDisplayOverlay() {
         synchronized(mWindowMap) {
 
-            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
                     ">>> OPEN TRANSACTION showEmulatorDisplayOverlay");
             SurfaceControl.openTransaction();
             try {
@@ -5658,7 +5660,7 @@
                 mEmulatorDisplayOverlay.setVisibility(true);
             } finally {
                 SurfaceControl.closeTransaction();
-                if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+                if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
                         "<<< CLOSE TRANSACTION showEmulatorDisplayOverlay");
             }
         }
@@ -5697,7 +5699,7 @@
                 }
             }
 
-            if (SHOW_VERBOSE_TRANSACTIONS) Slog.i(TAG,
+            if (SHOW_VERBOSE_TRANSACTIONS) Slog.i(TAG_WM,
                     ">>> OPEN TRANSACTION showStrictModeViolation");
             SurfaceControl.openTransaction();
             try {
@@ -5709,7 +5711,7 @@
                 mStrictModeFlash.setVisibility(on);
             } finally {
                 SurfaceControl.closeTransaction();
-                if (SHOW_VERBOSE_TRANSACTIONS) Slog.i(TAG,
+                if (SHOW_VERBOSE_TRANSACTIONS) Slog.i(TAG_WM,
                         "<<< CLOSE TRANSACTION showStrictModeViolation");
             }
         }
@@ -5796,7 +5798,7 @@
         synchronized(mWindowMap) {
             displayContent = getDisplayContentLocked(displayId);
             if (displayContent == null) {
-                if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot of " + appToken
+                if (DEBUG_SCREENSHOT) Slog.i(TAG_WM, "Screenshot of " + appToken
                         + ": returning null. No Display for displayId=" + displayId);
                 return null;
             }
@@ -5805,7 +5807,7 @@
         int dw = displayInfo.logicalWidth;
         int dh = displayInfo.logicalHeight;
         if (dw == 0 || dh == 0) {
-            if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot of " + appToken
+            if (DEBUG_SCREENSHOT) Slog.i(TAG_WM, "Screenshot of " + appToken
                     + ": returning null. logical widthxheight=" + dw + "x" + dh);
             return null;
         }
@@ -5927,21 +5929,21 @@
 
                 if (appToken != null && appWin == null) {
                     // Can't find a window to snapshot.
-                    if (DEBUG_SCREENSHOT) Slog.i(TAG,
+                    if (DEBUG_SCREENSHOT) Slog.i(TAG_WM,
                             "Screenshot: Couldn't find a surface matching " + appToken);
                     return null;
                 }
 
                 if (!screenshotReady) {
                     if (retryCount > MAX_SCREENSHOT_RETRIES) {
-                        Slog.i(TAG, "Screenshot max retries " + retryCount + " of " + appToken +
+                        Slog.i(TAG_WM, "Screenshot max retries " + retryCount + " of " + appToken +
                                 " appWin=" + (appWin == null ? "null" : (appWin + " drawState=" +
                                 appWin.mWinAnimator.mDrawState)));
                         return null;
                     }
 
                     // Delay and hope that window gets drawn.
-                    if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot: No image ready for " + appToken
+                    if (DEBUG_SCREENSHOT) Slog.i(TAG_WM, "Screenshot: No image ready for " + appToken
                             + ", " + appWin + " drawState=" + appWin.mWinAnimator.mDrawState);
                     continue;
                 }
@@ -5952,7 +5954,7 @@
                 // taken.
 
                 if (maxLayer == 0) {
-                    if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot of " + appToken
+                    if (DEBUG_SCREENSHOT) Slog.i(TAG_WM, "Screenshot of " + appToken
                             + ": returning null maxLayer=" + maxLayer);
                     return null;
                 }
@@ -6000,11 +6002,11 @@
                 convertCropForSurfaceFlinger(crop, rot, dw, dh);
 
                 if (DEBUG_SCREENSHOT) {
-                    Slog.i(TAG, "Screenshot: " + dw + "x" + dh + " from " + minLayer + " to "
+                    Slog.i(TAG_WM, "Screenshot: " + dw + "x" + dh + " from " + minLayer + " to "
                             + maxLayer + " appToken=" + appToken);
                     for (int i = 0; i < windows.size(); i++) {
                         WindowState win = windows.get(i);
-                        Slog.i(TAG, win + ": " + win.mLayer
+                        Slog.i(TAG_WM, win + ": " + win.mLayer
                                 + " animLayer=" + win.mWinAnimator.mAnimLayer
                                 + " surfaceLayer=" + win.mWinAnimator.mSurfaceController.getLayer());
                     }
@@ -6014,13 +6016,13 @@
                         mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
                 final boolean inRotation = screenRotationAnimation != null &&
                         screenRotationAnimation.isAnimating();
-                if (DEBUG_SCREENSHOT && inRotation) Slog.v(TAG,
+                if (DEBUG_SCREENSHOT && inRotation) Slog.v(TAG_WM,
                         "Taking screenshot while rotating");
 
                 bm = SurfaceControl.screenshot(crop, width, height, minLayer, maxLayer,
                         inRotation, rot);
                 if (bm == null) {
-                    Slog.w(TAG, "Screenshot failure taking screenshot for (" + dw + "x" + dh
+                    Slog.w(TAG_WM, "Screenshot failure taking screenshot for (" + dw + "x" + dh
                             + ") to layer " + maxLayer);
                     return null;
                 }
@@ -6042,7 +6044,7 @@
                 }
             }
             if (allBlack) {
-                Slog.i(TAG, "Screenshot " + appWin + " was monochrome(" +
+                Slog.i(TAG_WM, "Screenshot " + appWin + " was monochrome(" +
                         Integer.toHexString(firstColor) + ")! mSurfaceLayer=" +
                         (appWin != null ?
                                 appWin.mWinAnimator.mSurfaceController.getLayer() : "null") +
@@ -6074,7 +6076,7 @@
                     + "rotation constant.");
         }
 
-        if (DEBUG_ORIENTATION) Slog.v(TAG, "freezeRotation: mRotation=" + mRotation);
+        if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "freezeRotation: mRotation=" + mRotation);
 
         long origId = Binder.clearCallingIdentity();
         try {
@@ -6098,7 +6100,7 @@
             throw new SecurityException("Requires SET_ORIENTATION permission");
         }
 
-        if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation);
+        if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "thawRotation: mRotation=" + mRotation);
 
         long origId = Binder.clearCallingIdentity();
         try {
@@ -6152,7 +6154,7 @@
     }
 
     public void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {
-        if(DEBUG_ORIENTATION) Slog.v(TAG, "updateRotationUnchecked("
+        if(DEBUG_ORIENTATION) Slog.v(TAG_WM, "updateRotationUnchecked("
                    + "alwaysSendConfiguration=" + alwaysSendConfiguration + ")");
 
         long origId = Binder.clearCallingIdentity();
@@ -6183,7 +6185,7 @@
         if (mDeferredRotationPauseCount > 0) {
             // Rotation updates have been paused temporarily.  Defer the update until
             // updates have been resumed.
-            if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, rotation is paused.");
+            if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, rotation is paused.");
             return false;
         }
 
@@ -6193,13 +6195,13 @@
             // Rotation updates cannot be performed while the previous rotation change
             // animation is still in progress.  Skip this update.  We will try updating
             // again after the animation is finished and the display is unfrozen.
-            if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, animation in progress.");
+            if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, animation in progress.");
             return false;
         }
 
         if (!mDisplayEnabled) {
             // No point choosing a rotation if the display is not enabled.
-            if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, display is not enabled.");
+            if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, display is not enabled.");
             return false;
         }
 
@@ -6213,7 +6215,7 @@
                 mForcedAppOrientation, rotation);
 
         if (DEBUG_ORIENTATION) {
-            Slog.v(TAG, "Application requested orientation "
+            Slog.v(TAG_WM, "Application requested orientation "
                     + mForcedAppOrientation + ", got rotation " + rotation
                     + " which has " + (altOrientation ? "incompatible" : "compatible")
                     + " metrics");
@@ -6225,7 +6227,7 @@
         }
 
         if (DEBUG_ORIENTATION) {
-            Slog.v(TAG,
+            Slog.v(TAG_WM,
                 "Rotation changed to " + rotation + (altOrientation ? " (alt)" : "")
                 + " from " + mRotation + (mAltOrientation ? " (alt)" : "")
                 + ", forceApp=" + mForcedAppOrientation);
@@ -6262,7 +6264,7 @@
         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
         if (!inTransaction) {
             if (SHOW_TRANSACTIONS) {
-                Slog.i(TAG, ">>> OPEN TRANSACTION setRotationUnchecked");
+                Slog.i(TAG_WM, ">>> OPEN TRANSACTION setRotationUnchecked");
             }
             SurfaceControl.openTransaction();
         }
@@ -6284,7 +6286,7 @@
             if (!inTransaction) {
                 SurfaceControl.closeTransaction();
                 if (SHOW_LIGHT_TRANSACTIONS) {
-                    Slog.i(TAG, "<<< CLOSE TRANSACTION setRotationUnchecked");
+                    Slog.i(TAG_WM, "<<< CLOSE TRANSACTION setRotationUnchecked");
                 }
             }
         }
@@ -6297,7 +6299,7 @@
                 w.mAppToken.destroySavedSurfaces();
             }
             if (w.mHasSurface) {
-                if (DEBUG_ORIENTATION) Slog.v(TAG, "Set mOrientationChanging of " + w);
+                if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Set mOrientationChanging of " + w);
                 w.mOrientationChanging = true;
                 mWindowPlacerLocked.mOrientationChangeComplete = false;
             }
@@ -6467,7 +6469,7 @@
                 try {
                     return mViewServer.start();
                 } catch (IOException e) {
-                    Slog.w(TAG, "View server did not start");
+                    Slog.w(TAG_WM, "View server did not start");
                 }
             }
             return false;
@@ -6477,7 +6479,7 @@
             mViewServer = new ViewServer(this, port);
             return mViewServer.start();
         } catch (IOException e) {
-            Slog.w(TAG, "View server did not start");
+            Slog.w(TAG_WM, "View server did not start");
         }
         return false;
     }
@@ -6711,7 +6713,7 @@
             }
 
         } catch (Exception e) {
-            Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
+            Slog.w(TAG_WM, "Could not send command " + command + " with parameters " + parameters, e);
             success = false;
         } finally {
             if (data != null) {
@@ -6982,7 +6984,7 @@
 
         displayContent.mBaseDisplayRect.set(0, 0, dw, dh);
         if (false) {
-            Slog.i(TAG, "Set app display size: " + appWidth + " x " + appHeight);
+            Slog.i(TAG_WM, "Set app display size: " + appWidth + " x " + appHeight);
         }
 
         mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(mDisplayMetrics,
@@ -7125,7 +7127,7 @@
     }
 
     private void startScrollingTask(DisplayContent displayContent, int startX, int startY) {
-        if (DEBUG_TASK_POSITIONING) Slog.d(TAG,
+        if (DEBUG_TASK_POSITIONING) Slog.d(TAG_WM,
                 "startScrollingTask: " + "{" + startX + ", " + startY + "}");
 
         Task task = null;
@@ -7160,22 +7162,22 @@
 
     private boolean startPositioningLocked(
             WindowState win, boolean resize, float startX, float startY) {
-        if (DEBUG_TASK_POSITIONING) Slog.d(TAG, "startPositioningLocked: "
+        if (DEBUG_TASK_POSITIONING) Slog.d(TAG_WM, "startPositioningLocked: "
             + "win=" + win + ", resize=" + resize + ", {" + startX + ", " + startY + "}");
 
         if (win == null || win.getAppToken() == null) {
-            Slog.w(TAG, "startPositioningLocked: Bad window " + win);
+            Slog.w(TAG_WM, "startPositioningLocked: Bad window " + win);
             return false;
         }
         if (win.mInputChannel == null) {
-            Slog.wtf(TAG, "startPositioningLocked: " + win + " has no input channel, "
+            Slog.wtf(TAG_WM, "startPositioningLocked: " + win + " has no input channel, "
                     + " probably being removed");
             return false;
         }
 
         final DisplayContent displayContent = win.getDisplayContent();
         if (displayContent == null) {
-            Slog.w(TAG, "startPositioningLocked: Invalid display content " + win);
+            Slog.w(TAG_WM, "startPositioningLocked: Invalid display content " + win);
             return false;
         }
 
@@ -7185,7 +7187,7 @@
         mInputMonitor.updateInputWindowsLw(true /*force*/);
         if (!mInputManager.transferTouchFocus(
                 win.mInputChannel, mTaskPositioner.mServerChannel)) {
-            Slog.e(TAG, "startPositioningLocked: Unable to transfer touch focus");
+            Slog.e(TAG_WM, "startPositioningLocked: Unable to transfer touch focus");
             mTaskPositioner.unregister();
             mTaskPositioner = null;
             mInputMonitor.updateInputWindowsLw(true /*force*/);
@@ -7198,7 +7200,7 @@
 
     private void finishPositioning() {
         if (DEBUG_TASK_POSITIONING) {
-            Slog.d(TAG, "finishPositioning");
+            Slog.d(TAG_WM, "finishPositioning");
         }
         synchronized (mWindowMap) {
             if (mTaskPositioner != null) {
@@ -7216,7 +7218,7 @@
     IBinder prepareDragSurface(IWindow window, SurfaceSession session,
             int flags, int width, int height, Surface outSurface) {
         if (DEBUG_DRAG) {
-            Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
+            Slog.d(TAG_WM, "prepare drag surface: w=" + width + " h=" + height
                     + " flags=" + Integer.toHexString(flags) + " win=" + window
                     + " asbinder=" + window.asBinder());
         }
@@ -7243,7 +7245,7 @@
                         }
                         surface.setAlpha(alpha);
 
-                        if (SHOW_TRANSACTIONS) Slog.i(TAG, "  DRAG "
+                        if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, "  DRAG "
                                 + surface + ": CREATE");
                         outSurface.copyFrom(surface);
                         final IBinder winBinder = window.asBinder();
@@ -7259,10 +7261,10 @@
                         Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
                         mH.sendMessageDelayed(msg, 5000);
                     } else {
-                        Slog.w(TAG, "Drag already in progress");
+                        Slog.w(TAG_WM, "Drag already in progress");
                     }
                 } catch (OutOfResourcesException e) {
-                    Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
+                    Slog.e(TAG_WM, "Can't allocate drag surface w=" + width + " h=" + height, e);
                     if (mDragState != null) {
                         mDragState.reset();
                         mDragState = null;
@@ -7341,7 +7343,7 @@
     public boolean detectSafeMode() {
         if (!mInputMonitor.waitForInputDevicesReady(
                 INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
-            Slog.w(TAG, "Devices still not ready after waiting "
+            Slog.w(TAG_WM, "Devices still not ready after waiting "
                    + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
                    + " milliseconds before attempting to detect safe mode.");
         }
@@ -7365,10 +7367,10 @@
         } catch (IllegalArgumentException e) {
         }
         if (mSafeMode) {
-            Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
+            Log.i(TAG_WM, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
                     + " dpad=" + dpadState + " trackball=" + trackballState + ")");
         } else {
-            Log.i(TAG, "SAFE MODE not enabled");
+            Log.i(TAG_WM, "SAFE MODE not enabled");
         }
         mPolicy.setSafeMode(mSafeMode);
         return mSafeMode;
@@ -7489,7 +7491,7 @@
         @Override
         public void handleMessage(Message msg) {
             if (DEBUG_WINDOW_TRACE) {
-                Slog.v(TAG, "handleMessage: entry what=" + msg.what);
+                Slog.v(TAG_WM, "handleMessage: entry what=" + msg.what);
             }
             switch (msg.what) {
                 case REPORT_FOCUS_CHANGE: {
@@ -7512,11 +7514,11 @@
                             return;
                         }
                         mLastFocus = newFocus;
-                        if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Focus moving from " + lastFocus +
+                        if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Focus moving from " + lastFocus +
                                 " to " + newFocus);
                         if (newFocus != null && lastFocus != null
                                 && !newFocus.isDisplayedLw()) {
-                            //Slog.i(TAG, "Delaying loss of focus...");
+                            //Slog.i(TAG_WM, "Delaying loss of focus...");
                             mLosingFocus.add(lastFocus);
                             lastFocus = null;
                         }
@@ -7531,13 +7533,13 @@
                     //System.out.println("Changing focus from " + lastFocus
                     //                   + " to " + newFocus);
                     if (newFocus != null) {
-                        if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Gaining focus: " + newFocus);
+                        if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Gaining focus: " + newFocus);
                         newFocus.reportFocusChangedSerialized(true, mInTouchMode);
                         notifyFocusChanged();
                     }
 
                     if (lastFocus != null) {
-                        if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Losing focus: " + lastFocus);
+                        if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Losing focus: " + lastFocus);
                         lastFocus.reportFocusChangedSerialized(false, mInTouchMode);
                     }
                 } break;
@@ -7552,7 +7554,7 @@
 
                     final int N = losers.size();
                     for (int i=0; i<N; i++) {
-                        if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Losing delayed focus: " +
+                        if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Losing delayed focus: " +
                                 losers.get(i));
                         losers.get(i).reportFocusChangedSerialized(false, mInTouchMode);
                     }
@@ -7573,7 +7575,7 @@
                         return;
                     }
 
-                    if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
+                    if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Add starting "
                             + wtoken + ": pkg=" + sd.pkg);
 
                     View view = null;
@@ -7582,7 +7584,7 @@
                             wtoken.token, sd.pkg, sd.theme, sd.compatInfo,
                             sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.logo, sd.windowFlags);
                     } catch (Exception e) {
-                        Slog.w(TAG, "Exception when adding starting window", e);
+                        Slog.w(TAG_WM, "Exception when adding starting window", e);
                     }
 
                     if (view != null) {
@@ -7593,7 +7595,7 @@
                                 // If the window was successfully added, then
                                 // we need to remove it.
                                 if (wtoken.startingWindow != null) {
-                                    if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
+                                    if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
                                             "Aborted starting " + wtoken
                                             + ": removed=" + wtoken.removed
                                             + " startingData=" + wtoken.startingData);
@@ -7604,7 +7606,7 @@
                             } else {
                                 wtoken.startingView = view;
                             }
-                            if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
+                            if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG_WM,
                                     "Added starting " + wtoken
                                     + ": startingWindow="
                                     + wtoken.startingWindow + " startingView="
@@ -7615,7 +7617,7 @@
                             try {
                                 mPolicy.removeStartingWindow(wtoken.token, view);
                             } catch (Exception e) {
-                                Slog.w(TAG, "Exception when removing starting window", e);
+                                Slog.w(TAG_WM, "Exception when removing starting window", e);
                             }
                         }
                     }
@@ -7626,7 +7628,7 @@
                     IBinder token = null;
                     View view = null;
                     synchronized (mWindowMap) {
-                        if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
+                        if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Remove starting "
                                 + wtoken + ": startingWindow="
                                 + wtoken.startingWindow + " startingView="
                                 + wtoken.startingView);
@@ -7643,7 +7645,7 @@
                         try {
                             mPolicy.removeStartingWindow(token, view);
                         } catch (Exception e) {
-                            Slog.w(TAG, "Exception when removing starting window", e);
+                            Slog.w(TAG_WM, "Exception when removing starting window", e);
                         }
                     }
                 } break;
@@ -7659,7 +7661,7 @@
                             }
                             AppWindowToken wtoken = mFinishedStarting.remove(N-1);
 
-                            if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
+                            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
                                     "Finished starting " + wtoken
                                     + ": startingWindow=" + wtoken.startingWindow
                                     + " startingView=" + wtoken.startingView);
@@ -7679,7 +7681,7 @@
                         try {
                             mPolicy.removeStartingWindow(token, view);
                         } catch (Exception e) {
-                            Slog.w(TAG, "Exception when removing starting window", e);
+                            Slog.w(TAG_WM, "Exception when removing starting window", e);
                         }
                     }
                 } break;
@@ -7689,7 +7691,7 @@
 
                     try {
                         if (DEBUG_VISIBILITY) Slog.v(
-                                TAG, "Reporting drawn in " + wtoken);
+                                TAG_WM, "Reporting drawn in " + wtoken);
                         wtoken.appToken.windowsDrawn();
                     } catch (RemoteException ex) {
                     }
@@ -7703,7 +7705,7 @@
 
                     try {
                         if (DEBUG_VISIBILITY) Slog.v(
-                                TAG, "Reporting visible in " + wtoken
+                                TAG_WM, "Reporting visible in " + wtoken
                                 + " visible=" + nowVisible
                                 + " gone=" + nowGone);
                         if (nowVisible) {
@@ -7718,7 +7720,7 @@
                 case WINDOW_FREEZE_TIMEOUT: {
                     // TODO(multidisplay): Can non-default displays rotate?
                     synchronized (mWindowMap) {
-                        Slog.w(TAG, "Window freeze timeout expired.");
+                        Slog.w(TAG_WM, "Window freeze timeout expired.");
                         mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT;
                         final WindowList windows = getDefaultWindowListLocked();
                         int i = windows.size();
@@ -7729,7 +7731,7 @@
                                 w.mOrientationChanging = false;
                                 w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
                                         - mDisplayFreezeTime);
-                                Slog.w(TAG, "Force clearing orientation change: " + w);
+                                Slog.w(TAG_WM, "Force clearing orientation change: " + w);
                             }
                         }
                         mWindowPlacerLocked.performSurfacePlacement();
@@ -7741,7 +7743,7 @@
                     synchronized (mWindowMap) {
                         if (mAppTransition.isTransitionSet() || !mOpeningApps.isEmpty()
                                     || !mClosingApps.isEmpty()) {
-                            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** APP TRANSITION TIMEOUT."
+                            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "*** APP TRANSITION TIMEOUT."
                                     + " isTransitionSet()=" + mAppTransition.isTransitionSet()
                                     + " mOpeningApps.size()=" + mOpeningApps.size()
                                     + " mClosingApps.size()=" + mClosingApps.size());
@@ -7790,7 +7792,7 @@
 
                 case APP_FREEZE_TIMEOUT: {
                     synchronized (mWindowMap) {
-                        Slog.w(TAG, "App freeze timeout expired.");
+                        Slog.w(TAG_WM, "App freeze timeout expired.");
                         mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT;
                         final int numStacks = mStackIdToStack.size();
                         for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
@@ -7801,7 +7803,7 @@
                                 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
                                     AppWindowToken tok = tokens.get(tokenNdx);
                                     if (tok.mAppAnimator.freezingScreen) {
-                                        Slog.w(TAG, "Force clearing freeze: " + tok);
+                                        Slog.w(TAG_WM, "Force clearing freeze: " + tok);
                                         unsetAppFreezingScreenLocked(tok, true, true);
                                     }
                                 }
@@ -7841,7 +7843,7 @@
                 case DRAG_START_TIMEOUT: {
                     IBinder win = (IBinder)msg.obj;
                     if (DEBUG_DRAG) {
-                        Slog.w(TAG, "Timeout starting drag by win " + win);
+                        Slog.w(TAG_WM, "Timeout starting drag by win " + win);
                     }
                     synchronized (mWindowMap) {
                         // !!! TODO: ANR the app that has failed to start the drag in time
@@ -7858,7 +7860,7 @@
                 case DRAG_END_TIMEOUT: {
                     IBinder win = (IBinder)msg.obj;
                     if (DEBUG_DRAG) {
-                        Slog.w(TAG, "Timeout ending drag to win " + win);
+                        Slog.w(TAG_WM, "Timeout ending drag to win " + win);
                     }
                     synchronized (mWindowMap) {
                         // !!! TODO: ANR the drag-receiving app
@@ -7883,7 +7885,7 @@
                 case WAITING_FOR_DRAWN_TIMEOUT: {
                     Runnable callback = null;
                     synchronized (mWindowMap) {
-                        Slog.w(TAG, "Timeout waiting for drawn: undrawn=" + mWaitingForDrawn);
+                        Slog.w(TAG_WM, "Timeout waiting for drawn: undrawn=" + mWaitingForDrawn);
                         mWaitingForDrawn.clear();
                         callback = mWaitingForDrawnCallback;
                         mWaitingForDrawnCallback = null;
@@ -8008,7 +8010,7 @@
                 case CHECK_IF_BOOT_ANIMATION_FINISHED: {
                     final boolean bootAnimationComplete;
                     synchronized (mWindowMap) {
-                        if (DEBUG_BOOT) Slog.i(TAG, "CHECK_IF_BOOT_ANIMATION_FINISHED:");
+                        if (DEBUG_BOOT) Slog.i(TAG_WM, "CHECK_IF_BOOT_ANIMATION_FINISHED:");
                         bootAnimationComplete = checkBootAnimationCompleteLocked();
                     }
                     if (bootAnimationComplete) {
@@ -8065,7 +8067,7 @@
                 break;
             }
             if (DEBUG_WINDOW_TRACE) {
-                Slog.v(TAG, "handleMessage: exit");
+                Slog.v(TAG_WM, "handleMessage: exit");
             }
         }
     }
@@ -8100,9 +8102,9 @@
                 // TODO(multidisplay): IMEs are only supported on the default display.
                 WindowState imFocus = getDefaultWindowListLocked().get(idx-1);
                 if (DEBUG_INPUT_METHOD) {
-                    Slog.i(TAG, "Desired input method target: " + imFocus);
-                    Slog.i(TAG, "Current focus: " + mCurrentFocus);
-                    Slog.i(TAG, "Last focus: " + mLastFocus);
+                    Slog.i(TAG_WM, "Desired input method target: " + imFocus);
+                    Slog.i(TAG_WM, "Current focus: " + mCurrentFocus);
+                    Slog.i(TAG_WM, "Last focus: " + mLastFocus);
                 }
                 if (imFocus != null) {
                     // This may be a starting window, in which case we still want
@@ -8114,18 +8116,18 @@
                         for (int i=0; i<imFocus.mAppToken.windows.size(); i++) {
                             WindowState w = imFocus.mAppToken.windows.get(i);
                             if (w != imFocus) {
-                                Log.i(TAG, "Switching to real app window: " + w);
+                                Log.i(TAG_WM, "Switching to real app window: " + w);
                                 imFocus = w;
                                 break;
                             }
                         }
                     }
                     if (DEBUG_INPUT_METHOD) {
-                        Slog.i(TAG, "IM target client: " + imFocus.mSession.mClient);
+                        Slog.i(TAG_WM, "IM target client: " + imFocus.mSession.mClient);
                         if (imFocus.mSession.mClient != null) {
-                            Slog.i(TAG, "IM target client binder: "
+                            Slog.i(TAG_WM, "IM target client binder: "
                                     + imFocus.mSession.mClient.asBinder());
-                            Slog.i(TAG, "Requesting client binder: " + client.asBinder());
+                            Slog.i(TAG_WM, "Requesting client binder: " + client.asBinder());
                         }
                     }
                     if (imFocus.mSession.mClient != null &&
@@ -8238,7 +8240,7 @@
     }
 
     private void setForcedDisplayScalingModeLocked(DisplayContent displayContent, int mode) {
-        Slog.i(TAG, "Using display scaling mode: " + (mode == 0 ? "auto" : "off"));
+        Slog.i(TAG_WM, "Using display scaling mode: " + (mode == 0 ? "auto" : "off"));
         displayContent.mDisplayScalingDisabled = (mode != 0);
         reconfigureDisplayLocked(displayContent);
     }
@@ -8259,7 +8261,7 @@
                     height = Integer.parseInt(sizeStr.substring(pos+1));
                     if (displayContent.mBaseDisplayWidth != width
                             || displayContent.mBaseDisplayHeight != height) {
-                        Slog.i(TAG, "FORCED DISPLAY SIZE: " + width + "x" + height);
+                        Slog.i(TAG_WM, "FORCED DISPLAY SIZE: " + width + "x" + height);
                         displayContent.mBaseDisplayWidth = width;
                         displayContent.mBaseDisplayHeight = height;
                     }
@@ -8279,7 +8281,7 @@
             try {
                 density = Integer.parseInt(densityStr);
                 if (displayContent.mBaseDisplayDensity != density) {
-                    Slog.i(TAG, "FORCED DISPLAY DENSITY: " + density);
+                    Slog.i(TAG_WM, "FORCED DISPLAY DENSITY: " + density);
                     displayContent.mBaseDisplayDensity = density;
                 }
             } catch (NumberFormatException ex) {
@@ -8290,14 +8292,14 @@
         int mode = Settings.Global.getInt(mContext.getContentResolver(),
                 Settings.Global.DISPLAY_SCALING_FORCE, 0);
         if (mode != 0) {
-            Slog.i(TAG, "FORCED DISPLAY SCALING DISABLED");
+            Slog.i(TAG_WM, "FORCED DISPLAY SCALING DISABLED");
             displayContent.mDisplayScalingDisabled = true;
         }
     }
 
     // displayContent must not be null
     private void setForcedDisplaySizeLocked(DisplayContent displayContent, int width, int height) {
-        Slog.i(TAG, "Using new display size: " + width + "x" + height);
+        Slog.i(TAG_WM, "Using new display size: " + width + "x" + height);
         displayContent.mBaseDisplayWidth = width;
         displayContent.mBaseDisplayHeight = height;
         reconfigureDisplayLocked(displayContent);
@@ -8380,7 +8382,7 @@
 
     // displayContent must not be null
     private void setForcedDisplayDensityLocked(DisplayContent displayContent, int density) {
-        Slog.i(TAG, "Using new display density: " + density);
+        Slog.i(TAG_WM, "Using new display density: " + density);
         displayContent.mBaseDisplayDensity = density;
         reconfigureDisplayLocked(displayContent);
     }
@@ -8497,14 +8499,14 @@
             boolean throwOnError) {
         WindowState win = mWindowMap.get(client);
         if (localLOGV) Slog.v(
-            TAG, "Looking up client " + client + ": " + win);
+            TAG_WM, "Looking up client " + client + ": " + win);
         if (win == null) {
             RuntimeException ex = new IllegalArgumentException(
                     "Requested window " + client + " does not exist");
             if (throwOnError) {
                 throw ex;
             }
-            Slog.w(TAG, "Failed looking up window", ex);
+            Slog.w(TAG_WM, "Failed looking up window", ex);
             return null;
         }
         if (session != null && win.mSession != session) {
@@ -8514,7 +8516,7 @@
             if (throwOnError) {
                 throw ex;
             }
-            Slog.w(TAG, "Failed looking up window", ex);
+            Slog.w(TAG_WM, "Failed looking up window", ex);
             return null;
         }
 
@@ -8545,7 +8547,7 @@
                 win.mRebuilding = true;
                 mRebuildTmp[numRemoved] = win;
                 mWindowsChanged = true;
-                if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Rebuild removing window: " + win);
+                if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Rebuild removing window: " + win);
                 NW--;
                 numRemoved++;
                 continue;
@@ -8596,7 +8598,7 @@
         i -= lastBelow;
         if (i != numRemoved) {
             displayContent.layoutNeeded = true;
-            Slog.w(TAG, "On display=" + displayContent.getDisplayId() + " Rebuild removed " +
+            Slog.w(TAG_WM, "On display=" + displayContent.getDisplayId() + " Rebuild removed " +
                     numRemoved + " windows but added " + i,
                     new RuntimeException("here").fillInStackTrace());
             for (i=0; i<numRemoved; i++) {
@@ -8606,14 +8608,14 @@
                     PrintWriter pw = new FastPrintWriter(sw, false, 1024);
                     ws.dump(pw, "", true);
                     pw.flush();
-                    Slog.w(TAG, "This window was lost: " + ws);
-                    Slog.w(TAG, sw.toString());
+                    Slog.w(TAG_WM, "This window was lost: " + ws);
+                    Slog.w(TAG_WM, sw.toString());
                     ws.mWinAnimator.destroySurfaceLocked();
                 }
             }
-            Slog.w(TAG, "Current app token list:");
+            Slog.w(TAG_WM, "Current app token list:");
             dumpAppTokensLocked();
-            Slog.w(TAG, "Final window list:");
+            Slog.w(TAG_WM, "Final window list:");
             dumpWindowsLocked();
         }
         Arrays.fill(mRebuildTmp, null);
@@ -8625,7 +8627,7 @@
         int curLayer = 0;
         int i;
 
-        if (DEBUG_LAYERS) Slog.v(TAG, "Assigning layers based on windows=" + windows,
+        if (DEBUG_LAYERS) Slog.v(TAG_WM, "Assigning layers based on windows=" + windows,
                 new RuntimeException("here").fillInStackTrace());
 
         boolean anyLayerChanged = false;
@@ -8674,7 +8676,7 @@
                 // Force an animation pass just to update the mDimLayer layer.
                 scheduleAnimationLocked();
             }
-            if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
+            if (DEBUG_LAYERS) Slog.v(TAG_WM, "Assign layer " + w + ": "
                     + "mBase=" + w.mBaseLayer
                     + " mLayer=" + w.mLayer
                     + (wtoken == null ?
@@ -8703,8 +8705,8 @@
         }
         if (!force) {
             final TaskStack stack = w.getStack();
-            if (stack != null && StackId.isAlwaysOnTop(stack.mStackId)) {
-                // If the window's stack is always on top, we want to make it above other windows
+            if (stack != null && (StackId.shouldIncreaseApplicationWindowLayer(stack.mStackId))) {
+                // For pinned and docked stack window, we want to make them above other windows
                 // also when these windows are animating.
                 force = true;
             }
@@ -8720,7 +8722,7 @@
         // it frozen/off until this window draws at its new
         // orientation.
         if (!okToDisplay() && mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
-            if (DEBUG_ORIENTATION) Slog.v(TAG, "Changing surface while display frozen: " + w);
+            if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Changing surface while display frozen: " + w);
             w.mOrientationChanging = true;
             w.mLastFreezeDuration = 0;
             mWindowPlacerLocked.mOrientationChangeComplete = false;
@@ -8765,7 +8767,7 @@
         rebuildAppWindowListLocked();
 
         changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
-        if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+        if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG_WM,
                 "Wallpaper layer changed: assigning layers + relayout");
         moveInputMethodWindowsIfNeededLocked(true);
         mWindowPlacerLocked.mWallpaperMayChange = true;
@@ -8783,11 +8785,11 @@
             w.setInsetsChanged();
             boolean configChanged = w.isConfigChanged();
             if (DEBUG_CONFIGURATION && configChanged) {
-                Slog.v(TAG, "Win " + w + " config changed: "
+                Slog.v(TAG_WM, "Win " + w + " config changed: "
                         + mCurConfiguration);
             }
             final boolean dragResizingChanged = w.isDragResizeChanged();
-            if (localLOGV) Slog.v(TAG, "Resizing " + w
+            if (localLOGV) Slog.v(TAG_WM, "Resizing " + w
                     + ": configChanged=" + configChanged
                     + " dragResizingChanged=" + dragResizingChanged
                     + " last=" + w.mLastFrame + " frame=" + w.mFrame);
@@ -8799,7 +8801,7 @@
                     || configChanged
                     || dragResizingChanged) {
                 if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
-                    Slog.v(TAG, "Resize reasons for w=" + w + ": "
+                    Slog.v(TAG_WM, "Resize reasons for w=" + w + ": "
                             + " contentInsetsChanged=" + w.mContentInsetsChanged
                             + " " + w.mContentInsets.toShortString()
                             + " visibleInsetsChanged=" + w.mVisibleInsetsChanged
@@ -8833,7 +8835,7 @@
                 // application when it has finished drawing.
                 if (w.mOrientationChanging || dragResizingChanged) {
                     if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION || DEBUG_RESIZE) {
-                        Slog.v(TAG, "Orientation or resize start waiting for draw"
+                        Slog.v(TAG_WM, "Orientation or resize start waiting for draw"
                                 + ", mDrawState=DRAW_PENDING in " + w
                                 + ", surfaceController " + winAnimator.mSurfaceController);
                     }
@@ -8844,13 +8846,13 @@
                     }
                 }
                 if (!mResizingWindows.contains(w)) {
-                    if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
+                    if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG_WM,
                             "Resizing window " + w);
                     mResizingWindows.add(w);
                 }
             } else if (w.mOrientationChanging) {
                 if (w.isDrawnLw()) {
-                    if (DEBUG_ORIENTATION) Slog.v(TAG,
+                    if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
                             "Orientation not waiting for draw in "
                             + w + ", surfaceController " + winAnimator.mSurfaceController);
                     w.mOrientationChanging = false;
@@ -8867,22 +8869,22 @@
         }
         for (int j = mWaitingForDrawn.size() - 1; j >= 0; j--) {
             WindowState win = mWaitingForDrawn.get(j);
-            if (DEBUG_SCREEN_ON) Slog.i(TAG, "Waiting for drawn " + win +
+            if (DEBUG_SCREEN_ON) Slog.i(TAG_WM, "Waiting for drawn " + win +
                     ": removed=" + win.mRemoved + " visible=" + win.isVisibleLw() +
                     " mHasSurface=" + win.mHasSurface +
                     " drawState=" + win.mWinAnimator.mDrawState);
             if (win.mRemoved || !win.mHasSurface || !win.mPolicyVisibility) {
                 // Window has been removed or hidden; no draw will now happen, so stop waiting.
-                if (DEBUG_SCREEN_ON) Slog.w(TAG, "Aborted waiting for drawn: " + win);
+                if (DEBUG_SCREEN_ON) Slog.w(TAG_WM, "Aborted waiting for drawn: " + win);
                 mWaitingForDrawn.remove(win);
             } else if (win.hasDrawnLw()) {
                 // Window is now drawn (and shown).
-                if (DEBUG_SCREEN_ON) Slog.d(TAG, "Window drawn win=" + win);
+                if (DEBUG_SCREEN_ON) Slog.d(TAG_WM, "Window drawn win=" + win);
                 mWaitingForDrawn.remove(win);
             }
         }
         if (mWaitingForDrawn.isEmpty()) {
-            if (DEBUG_SCREEN_ON) Slog.d(TAG, "All windows drawn!");
+            if (DEBUG_SCREEN_ON) Slog.d(TAG_WM, "All windows drawn!");
             mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT);
             mH.sendEmptyMessage(H.ALL_WINDOWS_DRAWN);
         }
@@ -8962,7 +8964,7 @@
             // window list to make sure we haven't left any dangling surfaces
             // around.
 
-            Slog.i(TAG, "Out of memory for surface!  Looking for leaks...");
+            Slog.i(TAG_WM, "Out of memory for surface!  Looking for leaks...");
             final int numDisplays = mDisplayContents.size();
             for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
                 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
@@ -8972,7 +8974,7 @@
                     WindowStateAnimator wsa = ws.mWinAnimator;
                     if (wsa.mSurfaceController != null) {
                         if (!mSessions.contains(wsa.mSession)) {
-                            Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
+                            Slog.w(TAG_WM, "LEAKED SURFACE (session doesn't exist): "
                                     + ws + " surface=" + wsa.mSurfaceController
                                     + " token=" + ws.mToken
                                     + " pid=" + ws.mSession.mPid
@@ -8982,14 +8984,13 @@
                             mForceRemoves.add(ws);
                             leakedSurface = true;
                         } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
-                            Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
+                            Slog.w(TAG_WM, "LEAKED SURFACE (app token hidden): "
                                     + ws + " surface=" + wsa.mSurfaceController
                                     + " token=" + ws.mAppToken
-                                    + " saved=" + ws.mAppToken.mHasSavedSurface);
+                                    + " saved=" + ws.mAppToken.hasSavedSurface());
                             if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
                             wsa.destroySurface();
                             ws.setHasSurface(false);
-                            ws.mAppToken.mHasSavedSurface = false;
                             leakedSurface = true;
                         }
                     }
@@ -8997,7 +8998,7 @@
             }
 
             if (!leakedSurface) {
-                Slog.w(TAG, "No leaked surfaces; killing applicatons!");
+                Slog.w(TAG_WM, "No leaked surfaces; killing applicatons!");
                 SparseIntArray pidCandidates = new SparseIntArray();
                 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
                     final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
@@ -9030,7 +9031,7 @@
             if (leakedSurface || killedApps) {
                 // We managed to reclaim some memory, so get rid of the trouble
                 // surface and ask the app to request another one.
-                Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
+                Slog.w(TAG_WM, "Looks like we have reclaimed some memory, clearing surface for retry.");
                 if (surfaceController != null) {
                     if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
                             "RECOVER DESTROY", null);
@@ -9069,7 +9070,7 @@
                 newFocus = computeFocusedWindowLocked();
             }
 
-            if (DEBUG_FOCUS_LIGHT || localLOGV) Slog.v(TAG, "Changing focus from " +
+            if (DEBUG_FOCUS_LIGHT || localLOGV) Slog.v(TAG_WM, "Changing focus from " +
                     mCurrentFocus + " to " + newFocus + " Callers=" + Debug.getCallers(4));
             final WindowState oldFocus = mCurrentFocus;
             mCurrentFocus = newFocus;
@@ -9129,7 +9130,7 @@
             final WindowState win = windows.get(i);
 
             if (localLOGV || DEBUG_FOCUS) Slog.v(
-                TAG, "Looking for focus: " + i
+                TAG_WM, "Looking for focus: " + i
                 + " = " + win
                 + ", flags=" + win.mAttrs.flags
                 + ", canReceive=" + win.canReceiveKeys());
@@ -9142,7 +9143,7 @@
 
             // If this window's application has been removed, just skip it.
             if (wtoken != null && (wtoken.removed || wtoken.sendingToBottom)) {
-                if (DEBUG_FOCUS) Slog.v(TAG, "Skipping " + wtoken + " because "
+                if (DEBUG_FOCUS) Slog.v(TAG_WM, "Skipping " + wtoken + " because "
                         + (wtoken.removed ? "removed" : "sendingToBottom"));
                 continue;
             }
@@ -9163,7 +9164,7 @@
                         if (mFocusedApp == token && token.stackCanReceiveKeys()) {
                             // Whoops, we are below the focused app whose stack can receive keys...
                             // No focus for you!!!
-                            if (localLOGV || DEBUG_FOCUS_LIGHT) Slog.v(TAG,
+                            if (localLOGV || DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM,
                                     "findFocusedWindow: Reached focused app=" + mFocusedApp);
                             return null;
                         }
@@ -9175,12 +9176,12 @@
                 }
             }
 
-            if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "findFocusedWindow: Found new focus @ " + i +
+            if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Found new focus @ " + i +
                         " = " + win);
             return win;
         }
 
-        if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "findFocusedWindow: No focusable windows.");
+        if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: No focusable windows.");
         return null;
     }
 
@@ -9256,7 +9257,7 @@
         if (mWaitingForConfig || mAppsFreezingScreen > 0
                 || mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_ACTIVE
                 || mClientFreezingScreen || !mOpeningApps.isEmpty()) {
-            if (DEBUG_ORIENTATION) Slog.d(TAG,
+            if (DEBUG_ORIENTATION) Slog.d(TAG_WM,
                 "stopFreezingDisplayLocked: Returning mWaitingForConfig=" + mWaitingForConfig
                 + ", mAppsFreezingScreen=" + mAppsFreezingScreen
                 + ", mWindowsFreezingScreen=" + mWindowsFreezingScreen
@@ -9274,7 +9275,7 @@
             sb.append(" due to ");
             sb.append(mLastFinishedFreezeSource);
         }
-        Slog.i(TAG, sb.toString());
+        Slog.i(TAG_WM, sb.toString());
         mH.removeMessages(H.APP_FREEZE_TIMEOUT);
         mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
         if (PROFILE_ORIENTATION) {
@@ -9289,7 +9290,7 @@
                 mAnimator.getScreenRotationAnimationLocked(displayId);
         if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
                 && screenRotationAnimation.hasScreenshot()) {
-            if (DEBUG_ORIENTATION) Slog.i(TAG, "**** Dismissing screen rotation animation");
+            if (DEBUG_ORIENTATION) Slog.i(TAG_WM, "**** Dismissing screen rotation animation");
             // TODO(multidisplay): rotation on main screen only.
             DisplayInfo displayInfo = displayContent.getDisplayInfo();
             // Get rotation animation again, with new top window
@@ -9335,7 +9336,7 @@
         mScreenFrozenLock.release();
 
         if (updateRotation) {
-            if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
+            if (DEBUG_ORIENTATION) Slog.d(TAG_WM, "Performing post-rotate rotation");
             configChanged |= updateRotationUncheckedLocked(false);
         }
 
@@ -10074,7 +10075,7 @@
     private DisplayContent newDisplayContentLocked(final Display display) {
         DisplayContent displayContent = new DisplayContent(display, this);
         final int displayId = display.getDisplayId();
-        if (DEBUG_DISPLAY) Slog.v(TAG, "Adding display=" + display);
+        if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Adding display=" + display);
         mDisplayContents.put(displayId, displayContent);
 
         DisplayInfo displayInfo = displayContent.getDisplayInfo();
@@ -10178,7 +10179,7 @@
                 displayContent.mDeferredRemoval = true;
                 return;
             }
-            if (DEBUG_DISPLAY) Slog.v(TAG, "Removing display=" + displayContent);
+            if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + displayContent);
             mDisplayContents.delete(displayId);
             displayContent.close();
             if (displayId == Display.DEFAULT_DISPLAY) {
@@ -10215,10 +10216,10 @@
         synchronized (mWindowMap) {
             AppWindowToken appWindowToken = findAppWindowToken(token);
             if (appWindowToken == null || !appWindowToken.isVisible()) {
-                Slog.w(TAG, "Attempted to set replacing window on non-existing app token " + token);
+                Slog.w(TAG_WM, "Attempted to set replacing window on non-existing app token " + token);
                 return;
             }
-            if (DEBUG_ADD_REMOVE) Slog.d(TAG, "Marking app token " + appWindowToken
+            if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Marking app token " + appWindowToken
                     + " as replacing window.");
             appWindowToken.mWillReplaceWindow = true;
             appWindowToken.mHasReplacedWindow = false;
@@ -10228,7 +10229,7 @@
                 // Set-up dummy animation so we can start treating windows associated with this
                 // token like they are in transition before the new app window is ready for us to
                 // run the real transition animation.
-                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
                         "setReplacingWindow() Setting dummy animation on: " + appWindowToken);
                 appWindowToken.mAppAnimator.setDummyAnimation();
             }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 5e38492..5a589e3 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -83,14 +83,18 @@
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
-import static com.android.server.wm.WindowManagerService.DEBUG_ADD_REMOVE;
-import static com.android.server.wm.WindowManagerService.DEBUG_CONFIGURATION;
-import static com.android.server.wm.WindowManagerService.DEBUG_FOCUS_LIGHT;
-import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT;
-import static com.android.server.wm.WindowManagerService.DEBUG_ORIENTATION;
-import static com.android.server.wm.WindowManagerService.DEBUG_POWER;
-import static com.android.server.wm.WindowManagerService.DEBUG_RESIZE;
-import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 class WindowList extends ArrayList<WindowState> {
 }
@@ -99,7 +103,7 @@
  * A window in the window manager.
  */
 final class WindowState implements WindowManagerPolicy.WindowState {
-    static final String TAG = "WindowState";
+    static final String TAG = TAG_WITH_CLASS_NAME ? "WindowState" : TAG_WM;
 
     // The minimal size of a window within the usable area of the freeform stack.
     // TODO(multi-window): fix the min sizes when we have mininum width/height support,
@@ -255,13 +259,6 @@
      */
     int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
 
-    /**
-     * This is rectangle of the window's surface that is not covered by
-     * system decorations.
-     */
-    final Rect mSystemDecorRect = new Rect();
-    final Rect mLastSystemDecorRect = new Rect();
-
     // Current transformation being applied.
     float mGlobalScale=1;
     float mInvGlobalScale=1;
@@ -402,6 +399,10 @@
     /** When true this window can be displayed on screens owther than mOwnerUid's */
     private boolean mShowToOwnerOnly;
 
+    // Whether the window has a saved surface from last pause, which can be
+    // used to start an entering animation earlier.
+    public boolean mSurfaceSaved = false;
+
     /**
      * Wake lock for drawing.
      * Even though it's slightly more expensive to do so, we will use a separate wake lock
@@ -473,8 +474,7 @@
                     + WindowManagerService.TYPE_LAYER_OFFSET;
             mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
             mAttachedWindow = attachedWindow;
-            if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to "
-                    + mAttachedWindow);
+            if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + mAttachedWindow);
 
             final WindowList childWindows = mAttachedWindow.mChildWindows;
             final int numChildWindows = childWindows.size();
@@ -521,7 +521,7 @@
         }
 
         WindowState appWin = this;
-        while (appWin.mAttachedWindow != null) {
+        while (appWin.isChildWindow()) {
             appWin = appWin.mAttachedWindow;
         }
         WindowToken appToken = appWin.mToken;
@@ -620,7 +620,7 @@
         final int ph = mContainingFrame.height();
 
         if (!mParentFrame.equals(pf)) {
-            //Slog.i(TAG, "Window " + this + " content frame from " + mParentFrame
+            //Slog.i(TAG_WM, "Window " + this + " content frame from " + mParentFrame
             //        + " to " + pf);
             mParentFrame.set(pf);
             mContentChanged = true;
@@ -854,7 +854,7 @@
     @Override
     public int getBaseType() {
         WindowState win = this;
-        while (win.mAttachedWindow != null) {
+        while (win.isChildWindow()) {
             win = win.mAttachedWindow;
         }
         return win.mAttrs.type;
@@ -1235,8 +1235,8 @@
     void removeLocked() {
         disposeInputChannel();
 
-        if (mAttachedWindow != null) {
-            if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + this + " from " + mAttachedWindow);
+        if (isChildWindow()) {
+            if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + this + " from " + mAttachedWindow);
             mAttachedWindow.mChildWindows.remove(this);
         }
         mWinAnimator.destroyDeferredSurfaceLocked();
@@ -1670,22 +1670,43 @@
         return mAppToken != null && mAppToken.mAnimatingWithSavedSurface;
     }
 
-    boolean shouldSaveSurface() {
+    // Returns true if the surface is saved.
+    boolean destroyOrSaveSurface() {
+        Task task = getTask();
         if (ActivityManager.isLowRamDeviceStatic()) {
             // Don't save surfaces on Svelte devices.
-            return false;
-        }
-
-        Task task = getTask();
-        if (task == null || task.inHomeStack()
+            mSurfaceSaved = false;
+        } else if (task == null || task.inHomeStack()
                 || task.getTopVisibleAppToken() != mAppToken) {
             // Don't save surfaces for home stack apps. These usually resume and draw
             // first frame very fast. Saving surfaces are mostly a waste of memory.
             // Don't save if the window is not the topmost window.
-            return false;
+            mSurfaceSaved = false;
+        } else if (isChildWindow()) {
+            mSurfaceSaved = false;
+        } else {
+            mSurfaceSaved = mAppToken.shouldSaveSurface();
         }
+        if (mSurfaceSaved == false) {
+            mWinAnimator.destroySurfaceLocked();
+        }
+        return mSurfaceSaved;
+    }
 
-        return mAppToken.shouldSaveSurface();
+    public void destroySavedSurface() {
+        if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "Destroying saved surface: " + this);
+        if (mSurfaceSaved) {
+            mWinAnimator.destroySurfaceLocked();
+        }
+    }
+
+    public boolean hasSavedSurface() {
+        return mSurfaceSaved;
+    }
+
+    public void restoreSavedSurface() {
+        mSurfaceSaved = false;
+        mWinAnimator.mDrawState = WindowStateAnimator.READY_TO_SHOW;
     }
 
     @Override
@@ -1712,7 +1733,7 @@
     boolean isHiddenFromUserLocked() {
         // Attached windows are evaluated based on the window that they are attached to.
         WindowState win = this;
-        while (win.mAttachedWindow != null) {
+        while (win.isChildWindow()) {
             win = win.mAttachedWindow;
         }
         if (win.mAttrs.type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW
@@ -1976,7 +1997,7 @@
             pw.print(prefix); pw.print("LastRequested w="); pw.print(mLastRequestedWidth);
                     pw.print(" h="); pw.println(mLastRequestedHeight);
         }
-        if (mAttachedWindow != null || mLayoutAttached) {
+        if (isChildWindow() || mLayoutAttached) {
             pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
                     pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
         }
@@ -2057,13 +2078,6 @@
             pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
                     pw.print(" last="); mLastFrame.printShortString(pw);
                     pw.println();
-            pw.print(prefix); pw.print("mSystemDecorRect="); mSystemDecorRect.printShortString(pw);
-                    pw.print(" last="); mLastSystemDecorRect.printShortString(pw);
-                    if (mWinAnimator.mHasClipRect) {
-                        pw.print(" mLastClipRect=");
-                        mWinAnimator.mLastClipRect.printShortString(pw);
-                    }
-                    pw.println();
         }
         if (mEnforceSizeCompat) {
             pw.print(prefix); pw.print("mCompatFrame="); mCompatFrame.printShortString(pw);
@@ -2241,4 +2255,8 @@
         // Now make sure the window fits in the overall display frame.
         Gravity.applyDisplay(mAttrs.gravity, mDisplayFrame, mFrame);
     }
+
+    boolean isChildWindow() {
+        return mAttachedWindow != null;
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 132b1b6..539810d 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -20,15 +20,21 @@
 import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
 import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-import static com.android.server.wm.WindowManagerService.DEBUG_ANIM;
-import static com.android.server.wm.WindowManagerService.DEBUG_LAYERS;
-import static com.android.server.wm.WindowManagerService.DEBUG_ORIENTATION;
-import static com.android.server.wm.WindowManagerService.DEBUG_STARTING_WINDOW;
-import static com.android.server.wm.WindowManagerService.DEBUG_SURFACE_TRACE;
-import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
-import static com.android.server.wm.WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
-import static com.android.server.wm.WindowManagerService.SHOW_SURFACE_ALLOC;
-import static com.android.server.wm.WindowManagerService.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_CROP;
+import static com.android.server.wm.WindowManagerDebugConfig.HIDE_STACK_CRAWLS;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
 import static com.android.server.wm.WindowManagerService.localLOGV;
 import static com.android.server.wm.WindowState.DRAG_RESIZE_MODE_FREEFORM;
@@ -64,7 +70,7 @@
  * Keep track of animations and surface operations for a single WindowState.
  **/
 class WindowStateAnimator {
-    static final String TAG = "WindowStateAnimator";
+    static final String TAG = TAG_WITH_CLASS_NAME ? "WindowStateAnimator" : TAG_WM;
     static final int WINDOW_FREEZE_LAYER = TYPE_LAYER_MULTIPLIER * 200;
 
     // Unchanging local convenience fields.
@@ -123,6 +129,13 @@
     Rect mLastClipRect = new Rect();
     Rect mTmpStackBounds = new Rect();
 
+    /**
+     * This is rectangle of the window's surface that is not covered by
+     * system decorations.
+     */
+    private final Rect mSystemDecorRect = new Rect();
+    private final Rect mLastSystemDecorRect = new Rect();
+
     // Used to save animation distances between the time they are calculated and when they are used.
     private int mAnimDx;
     private int mAnimDy;
@@ -402,7 +415,7 @@
         finishExit();
         final int displayId = mWin.getDisplayId();
         mAnimator.setPendingLayoutChanges(displayId, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
-        if (WindowManagerService.DEBUG_LAYOUT_REPEATS)
+        if (DEBUG_LAYOUT_REPEATS)
             mService.mWindowPlacerLocked.debugLayoutRepeats(
                     "WindowStateAnimator", mAnimator.getPendingLayoutChanges(displayId));
 
@@ -414,7 +427,7 @@
     }
 
     void finishExit() {
-        if (WindowManagerService.DEBUG_ANIM) Slog.v(
+        if (DEBUG_ANIM) Slog.v(
                 TAG, "finishExit in " + this
                 + ": exiting=" + mWin.mExiting
                 + " remove=" + mWin.mRemoveOnExit
@@ -594,7 +607,7 @@
             }
 
             // We may abort, so initialize to defaults.
-            w.mLastSystemDecorRect.set(0, 0, 0, 0);
+            mLastSystemDecorRect.set(0, 0, 0, 0);
             mHasClipRect = false;
             mClipRect.set(0, 0, 0, 0);
             mLastClipRect.set(0, 0, 0, 0);
@@ -660,7 +673,7 @@
 
             // Start a new transaction and apply position & offset.
             final int layerStack = w.getDisplayContent().getDisplay().getLayerStack();
-            if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
+            if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
                     "POS " + mTmpSize.left + ", " + mTmpSize.top, null);
             mSurfaceController.setPositionAndLayer(mTmpSize.left, mTmpSize.top, layerStack,
                     mAnimLayer);
@@ -726,13 +739,14 @@
     void destroySurfaceLocked() {
         final AppWindowToken wtoken = mWin.mAppToken;
         if (wtoken != null) {
-            wtoken.mHasSavedSurface = false;
             wtoken.mAnimatingWithSavedSurface = false;
             if (mWin == wtoken.startingWindow) {
                 wtoken.startingDisplayed = false;
             }
         }
 
+        mWin.mSurfaceSaved = false;
+
         if (mSurfaceController != null) {
             int i = mWin.mChildWindows.size();
             // When destroying a surface we want to make sure child windows
@@ -749,7 +763,7 @@
             try {
                 if (DEBUG_VISIBILITY) {
                     RuntimeException e = null;
-                    if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+                    if (!HIDE_STACK_CRAWLS) {
                         e = new RuntimeException();
                         e.fillInStackTrace();
                     }
@@ -761,7 +775,7 @@
                         if (mPendingDestroySurface != null) {
                             if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
                                 RuntimeException e = null;
-                                if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+                                if (!HIDE_STACK_CRAWLS) {
                                     e = new RuntimeException();
                                     e.fillInStackTrace();
                                 }
@@ -774,7 +788,7 @@
                 } else {
                     if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
                         RuntimeException e = null;
-                        if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+                        if (!HIDE_STACK_CRAWLS) {
                             e = new RuntimeException();
                             e.fillInStackTrace();
                         }
@@ -810,7 +824,7 @@
             if (mPendingDestroySurface != null) {
                 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
                     RuntimeException e = null;
-                    if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+                    if (!HIDE_STACK_CRAWLS) {
                         e = new RuntimeException();
                         e.fillInStackTrace();
                     }
@@ -849,7 +863,7 @@
                     wallpaperAnimator.mAnimation != null &&
                     !wallpaperAnimator.mAnimation.getDetachWallpaper()) {
                 attachedTransformation = wallpaperAnimator.mTransformation;
-                if (WindowManagerService.DEBUG_WALLPAPER && attachedTransformation != null) {
+                if (DEBUG_WALLPAPER && attachedTransformation != null) {
                     Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
                 }
             }
@@ -859,7 +873,7 @@
                     && wpAppAnimator.animation != null
                     && !wpAppAnimator.animation.getDetachWallpaper()) {
                 appTransformation = wpAppAnimator.transformation;
-                if (WindowManagerService.DEBUG_WALLPAPER && appTransformation != null) {
+                if (DEBUG_WALLPAPER && appTransformation != null) {
                     Slog.v(TAG, "WP target app xform: " + appTransformation);
                 }
             }
@@ -930,7 +944,7 @@
             // (a 2x2 matrix + an offset)
             // Here we must not transform the position of the surface
             // since it is already included in the transformation.
-            //Slog.i(TAG, "Transform: " + matrix);
+            //Slog.i(TAG_WM, "Transform: " + matrix);
 
             mHaveMatrix = true;
             tmpMatrix.getValues(tmpFloats);
@@ -952,7 +966,7 @@
                     || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format)
                     || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
                             && x == frame.left && y == frame.top))) {
-                //Slog.i(TAG, "Applying alpha transform");
+                //Slog.i(TAG_WM, "Applying alpha transform");
                 if (selfTransformation) {
                     mShownAlpha *= mTransformation.getAlpha();
                 }
@@ -970,7 +984,7 @@
                     mShownAlpha *= screenRotationAnimation.getEnterTransformation().getAlpha();
                 }
             } else {
-                //Slog.i(TAG, "Not applying alpha transform");
+                //Slog.i(TAG_WM, "Not applying alpha transform");
             }
 
             if ((DEBUG_SURFACE_TRACE || WindowManagerService.localLOGV)
@@ -1042,8 +1056,9 @@
         }
     }
 
-    private void applyDecorRect(final Rect decorRect) {
+    private void calculateSystemDecorRect() {
         final WindowState w = mWin;
+        final Rect decorRect = w.mDecorFrame;
         final int width = w.mFrame.width();
         final int height = w.mFrame.height();
 
@@ -1052,11 +1067,17 @@
         final int top = w.mYOffset + w.mFrame.top;
 
         // Initialize the decor rect to the entire frame.
-        w.mSystemDecorRect.set(0, 0, width, height);
+        mSystemDecorRect.set(0, 0, width, height);
 
-        // Intersect with the decor rect, offsetted by window position.
-        w.mSystemDecorRect.intersect(decorRect.left - left, decorRect.top - top,
-                decorRect.right - left, decorRect.bottom - top);
+        // If a freeform window is animating from a position where it would be cutoff, it would be
+        // cutoff during the animation. We don't want that, so for the duration of the animation
+        // we ignore the decor cropping and depend on layering to position windows correctly.
+        final boolean cropToDecor = !(w.inFreeformWorkspace() && w.isAnimatingLw());
+        if (cropToDecor) {
+            // Intersect with the decor rect, offsetted by window position.
+            mSystemDecorRect.intersect(decorRect.left - left, decorRect.top - top,
+                    decorRect.right - left, decorRect.bottom - top);
+        }
 
         // If size compatibility is being applied to the window, the
         // surface is scaled relative to the screen.  Also apply this
@@ -1066,10 +1087,10 @@
         // much and hide part of the window that should be seen.
         if (w.mEnforceSizeCompat && w.mInvGlobalScale != 1.0f) {
             final float scale = w.mInvGlobalScale;
-            w.mSystemDecorRect.left = (int) (w.mSystemDecorRect.left * scale - 0.5f);
-            w.mSystemDecorRect.top = (int) (w.mSystemDecorRect.top * scale - 0.5f);
-            w.mSystemDecorRect.right = (int) ((w.mSystemDecorRect.right+1) * scale - 0.5f);
-            w.mSystemDecorRect.bottom = (int) ((w.mSystemDecorRect.bottom+1) * scale - 0.5f);
+            mSystemDecorRect.left = (int) (mSystemDecorRect.left * scale - 0.5f);
+            mSystemDecorRect.top = (int) (mSystemDecorRect.top * scale - 0.5f);
+            mSystemDecorRect.right = (int) ((mSystemDecorRect.right+1) * scale - 0.5f);
+            mSystemDecorRect.bottom = (int) ((mSystemDecorRect.bottom+1) * scale - 0.5f);
         }
     }
 
@@ -1080,45 +1101,53 @@
             return;
         }
         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
+        if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Updating crop for window: " + w + ", " + "mLastCrop=" +
+                mLastClipRect);
 
         // Need to recompute a new system decor rect each time.
         if (!w.isDefaultDisplay()) {
             // On a different display there is no system decor.  Crop the window
             // by the screen boundaries.
-            w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
-            w.mSystemDecorRect.intersect(-w.mCompatFrame.left, -w.mCompatFrame.top,
+            mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
+            mSystemDecorRect.intersect(-w.mCompatFrame.left, -w.mCompatFrame.top,
                     displayInfo.logicalWidth - w.mCompatFrame.left,
                     displayInfo.logicalHeight - w.mCompatFrame.top);
         } else if (w.mLayer >= mService.mSystemDecorLayer) {
             // Above the decor layer is easy, just use the entire window.
-            w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
+            mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
         } else if (w.mDecorFrame.isEmpty()) {
             // Windows without policy decor aren't cropped.
-            w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
+            mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
         } else if (w.mAttrs.type == LayoutParams.TYPE_WALLPAPER && mAnimator.isAnimating()) {
             // If we're animating, the wallpaper crop should only be updated at the end of the
             // animation.
-            mTmpClipRect.set(w.mSystemDecorRect);
-            applyDecorRect(w.mDecorFrame);
-            w.mSystemDecorRect.union(mTmpClipRect);
+            mTmpClipRect.set(mSystemDecorRect);
+            calculateSystemDecorRect();
+            mSystemDecorRect.union(mTmpClipRect);
         } else {
             // Crop to the system decor specified by policy.
-            applyDecorRect(w.mDecorFrame);
+            calculateSystemDecorRect();
+            if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Applying decor to crop for " + w + ", mDecorFrame="
+                    + w.mDecorFrame + ", mSystemDecorRect=" + mSystemDecorRect);
         }
 
         final boolean fullscreen = w.isFrameFullscreen(displayInfo);
         final boolean isFreeformResizing =
                 w.isDragResizing() && w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM;
         final Rect clipRect = mTmpClipRect;
-        if (isFreeformResizing) {
-            // When we're doing a drag-resizing, the surface is set up to cover full screen.
-            // Set the clip rect to be the same size so that we don't get any scaling.
-            clipRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
-        } else {
-            // We use the clip rect as provided by the tranformation for non-fullscreen windows to
-            // avoid premature clipping with the system decor rect.
-            clipRect.set((mHasClipRect && !fullscreen) ? mClipRect : w.mSystemDecorRect);
+
+        // We use the clip rect as provided by the tranformation for non-fullscreen windows to
+        // avoid premature clipping with the system decor rect.
+        clipRect.set((mHasClipRect && !fullscreen) ? mClipRect : mSystemDecorRect);
+        if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Initial clip rect: " + clipRect + ", mHasClipRect="
+                + mHasClipRect + ", fullscreen=" + fullscreen);
+
+        if (isFreeformResizing && !w.isChildWindow()) {
+            // For freeform resizing non child windows, we are using the big surface positioned
+            // at 0,0. Thus we must express the crop in that coordinate space.
+            clipRect.offset(w.mShownPosition.x, w.mShownPosition.y);
         }
+
         // Expand the clip rect for surface insets.
         final WindowManager.LayoutParams attrs = w.mAttrs;
         clipRect.left -= attrs.surfaceInsets.left;
@@ -1137,6 +1166,7 @@
         clipRect.offset(attrs.surfaceInsets.left, attrs.surfaceInsets.top);
 
         adjustCropToStackBounds(w, clipRect, isFreeformResizing);
+        if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Clip rect after stack adjustment=" + mClipRect);
 
         w.transformFromScreenToSurfaceSpace(clipRect);
 
@@ -1154,13 +1184,14 @@
         }
 
         // We don't apply the stack bounds crop if:
-        // 1. The window is currently animating docked mode, otherwise the animating window will be
-        // suddenly cut off.
+        // 1. The window is currently animating docked mode or in freeform mode, otherwise the
+        // animating window will be suddenly (docked) or for whole animation (freeform) cut off.
         // 2. The window that is being replaced during animation, because it was living in a
         // different stack. If we suddenly crop it to the new stack bounds, it might get cut off.
         // We don't want it to happen, so we let it ignore the stack bounds until it gets removed.
         // The window that will replace it will abide them.
-        if (isAnimating() && (appToken.mWillReplaceWindow || w.inDockedWorkspace())) {
+        if (isAnimating() && (appToken.mWillReplaceWindow || w.inDockedWorkspace()
+                || w.inFreeformWorkspace())) {
             return;
         }
 
@@ -1262,7 +1293,7 @@
             mLastDtDy = mDtDy;
             w.mLastHScale = w.mHScale;
             w.mLastVScale = w.mVScale;
-            if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
+            if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
                     "controller=" + mSurfaceController +
                     "alpha=" + mShownAlpha + " layer=" + mAnimLayer
                     + " matrix=[" + mDsDx + "*" + w.mHScale
@@ -1460,10 +1491,8 @@
                 mWin.mAppToken.removeAllDeadWindows();
 
                 if (mWin.mAppToken.startingData != null) {
-                    if (WindowManagerService.DEBUG_STARTING_WINDOW ||
-                            WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
-                            "Finish starting " + mWin.mToken
-                            + ": first real window is shown, no animation");
+                    if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG, "Finish starting "
+                            + mWin.mToken + ": first real window is shown, no animation");
                     // If this initial window is animating, stop it -- we
                     // will do an animation to reveal it from behind the
                     // starting window, so there is no need for it to also
@@ -1574,16 +1603,16 @@
                     a = mService.mAppTransition.loadAnimationAttr(mWin.mAttrs, attr);
                 }
             }
-            if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
+            if (DEBUG_ANIM) Slog.v(TAG,
                     "applyAnimation: win=" + this
                     + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
                     + " a=" + a
                     + " transit=" + transit
                     + " isEntrance=" + isEntrance + " Callers " + Debug.getCallers(3));
             if (a != null) {
-                if (WindowManagerService.DEBUG_ANIM) {
+                if (DEBUG_ANIM) {
                     RuntimeException e = null;
-                    if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+                    if (!HIDE_STACK_CRAWLS) {
                         e = new RuntimeException();
                         e.fillInStackTrace();
                     }
@@ -1642,6 +1671,12 @@
         if (dumpAll) {
             pw.print(prefix); pw.print("mDrawState="); pw.print(drawStateToString());
             pw.print(prefix); pw.print(" mLastHidden="); pw.println(mLastHidden);
+            pw.print(prefix); pw.print("mSystemDecorRect="); mSystemDecorRect.printShortString(pw);
+            pw.print(" last="); mLastSystemDecorRect.printShortString(pw);
+            if (mHasClipRect) {
+                pw.print(" mLastClipRect="); mLastClipRect.printShortString(pw);
+            }
+            pw.println();
         }
 
         if (mPendingDestroySurface != null) {
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index f8b8d6c..bd2912d 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -16,12 +16,14 @@
 
 package com.android.server.wm;
 
-import static com.android.server.wm.WindowManagerService.SHOW_TRANSACTIONS;
-import static com.android.server.wm.WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
-import static com.android.server.wm.WindowManagerService.SHOW_SURFACE_ALLOC;
-import static com.android.server.wm.WindowManagerService.DEBUG_SURFACE_TRACE;
-import static com.android.server.wm.WindowManagerService.HIDE_STACK_CRAWLS;
-import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
+import static com.android.server.wm.WindowManagerDebugConfig.HIDE_STACK_CRAWLS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 import android.graphics.Point;
 import android.graphics.PointF;
@@ -41,7 +43,7 @@
 import java.util.ArrayList;
 
 class WindowSurfaceController {
-    static final String TAG = "WindowSurfaceController";
+    static final String TAG = TAG_WITH_CLASS_NAME ? "WindowSurfaceController" : TAG_WM;
 
     final WindowStateAnimator mAnimator;
 
@@ -392,7 +394,7 @@
     }
 
     static class SurfaceTrace extends SurfaceControl {
-        private final static String SURFACE_TAG = "SurfaceTrace";
+        private final static String SURFACE_TAG = TAG_WITH_CLASS_NAME ? "SurfaceTrace" : TAG_WM;
         private final static boolean LOG_SURFACE_TRACE = DEBUG_SURFACE_TRACE;
         final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>();
 
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 2149019..50bdf25 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -15,24 +15,24 @@
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-import static com.android.server.wm.WindowManagerService.DEBUG;
-import static com.android.server.wm.WindowManagerService.DEBUG_ADD_REMOVE;
-import static com.android.server.wm.WindowManagerService.DEBUG_APP_TRANSITIONS;
-import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT;
-import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT_REPEATS;
-import static com.android.server.wm.WindowManagerService.DEBUG_ORIENTATION;
-import static com.android.server.wm.WindowManagerService.DEBUG_POWER;
-import static com.android.server.wm.WindowManagerService.DEBUG_STARTING_WINDOW;
-import static com.android.server.wm.WindowManagerService.DEBUG_TOKEN_MOVEMENT;
-import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
-import static com.android.server.wm.WindowManagerService.DEBUG_WALLPAPER_LIGHT;
-import static com.android.server.wm.WindowManagerService.DEBUG_WINDOW_TRACE;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
 import static com.android.server.wm.WindowManagerService.H.*;
 import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
 import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
-import static com.android.server.wm.WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
-import static com.android.server.wm.WindowManagerService.SHOW_TRANSACTIONS;
-import static com.android.server.wm.WindowManagerService.TAG;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
 import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
@@ -54,7 +54,7 @@
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.View;
-import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
 import android.view.animation.Animation;
 
 import java.io.PrintWriter;
@@ -112,6 +112,12 @@
     private boolean mTraversalScheduled;
     private int mDeferDepth = 0;
 
+    private static final class LayerAndToken {
+        public int layer;
+        public AppWindowToken token;
+    }
+    private final LayerAndToken mTmpLayerAndToken = new LayerAndToken();
+
     public WindowSurfacePlacer(WindowManagerService service) {
         mService = service;
         mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
@@ -153,7 +159,7 @@
             if (DEBUG) {
                 throw new RuntimeException("Recursive call!");
             }
-            Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
+            Slog.w(TAG_WM, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
                     + Debug.getCallers(3));
             return;
         }
@@ -179,10 +185,10 @@
             // Wait a little bit for things to settle down, and off we go.
             while (!mService.mForceRemoves.isEmpty()) {
                 WindowState ws = mService.mForceRemoves.remove(0);
-                Slog.i(TAG, "Force removing: " + ws);
+                Slog.i(TAG_WM, "Force removing: " + ws);
                 mService.removeWindowInnerLocked(ws);
             }
-            Slog.w(TAG,
+            Slog.w(TAG_WM,
                     "Due to memory failure, waiting a bit for next layout");
             Object tmp = new Object();
             synchronized (tmp) {
@@ -202,7 +208,7 @@
                 if (++mLayoutRepeatCount < 6) {
                     requestTraversal();
                 } else {
-                    Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
+                    Slog.e(TAG_WM, "Performed 6 layouts in a row. Skipping");
                     mLayoutRepeatCount = 0;
                 }
             } else {
@@ -215,7 +221,7 @@
             }
         } catch (RuntimeException e) {
             mInLayout = false;
-            Slog.wtf(TAG, "Unhandled exception while laying out windows", e);
+            Slog.wtf(TAG_WM, "Unhandled exception while laying out windows", e);
         }
 
         Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
@@ -223,7 +229,7 @@
 
     void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
         if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
-            Slog.v(TAG, "Layouts looping: " + msg +
+            Slog.v(TAG_WM, "Layouts looping: " + msg +
                     ", mPendingLayoutChanges = 0x" + Integer.toHexString(pendingLayoutChanges));
         }
     }
@@ -231,7 +237,7 @@
     // "Something has changed!  Let's make it correct now."
     private void performSurfacePlacementInner(boolean recoveringMemory) {
         if (DEBUG_WINDOW_TRACE) {
-            Slog.v(TAG,
+            Slog.v(TAG_WM,
                     "performSurfacePlacementInner: entry. Called by "
                     + Debug.getCallers(3));
         }
@@ -276,16 +282,16 @@
         final int defaultDw = defaultInfo.logicalWidth;
         final int defaultDh = defaultInfo.logicalHeight;
 
-        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
                 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
         SurfaceControl.openTransaction();
         try {
             applySurfaceChangesTransaction(recoveringMemory, numDisplays, defaultDw, defaultDh);
         } catch (RuntimeException e) {
-            Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
+            Slog.wtf(TAG_WM, "Unhandled exception in Window Manager", e);
         } finally {
             SurfaceControl.closeTransaction();
-            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
                     "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
         }
 
@@ -332,7 +338,7 @@
 
         if (mWallpaperMayChange) {
             if (DEBUG_WALLPAPER_LIGHT)
-                Slog.v(TAG, "Wallpaper may change!  Adjusting");
+                Slog.v(TAG_WM, "Wallpaper may change!  Adjusting");
             defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
             if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
                     defaultDisplay.pendingLayoutChanges);
@@ -368,7 +374,7 @@
         }
 
         if (DEBUG_ORIENTATION && mService.mDisplayFrozen)
-            Slog.v(TAG,
+            Slog.v(TAG_WM,
                 "With display frozen, orientationChangeComplete="
                 + mOrientationChangeComplete);
         if (mOrientationChangeComplete) {
@@ -394,9 +400,7 @@
                 if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
                     wallpaperDestroyed = true;
                 }
-                if (!win.shouldSaveSurface()) {
-                    win.mWinAnimator.destroySurfaceLocked();
-                }
+                win.destroyOrSaveSurface();
             } while (i > 0);
             mService.mDestroySurface.clear();
         }
@@ -431,7 +435,7 @@
                     token.mAppAnimator.clearAnimation();
                     token.mAppAnimator.animating = false;
                     if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT)
-                        Slog.v(TAG,
+                        Slog.v(TAG_WM,
                                 "performLayout: App token exiting now removed" + token);
                     token.removeAppFromTaskLocked();
                 }
@@ -477,7 +481,7 @@
                     || Settings.Global.getInt(mService.mContext.getContentResolver(),
                         Settings.Global.THEATER_MODE_ON, 0) == 0) {
                 if (DEBUG_VISIBILITY || DEBUG_POWER) {
-                    Slog.v(TAG, "Turning screen on after layout!");
+                    Slog.v(TAG_WM, "Turning screen on after layout!");
                 }
                 mService.mPowerManager.wakeUp(SystemClock.uptimeMillis(),
                         "android.server.wm:TURN_ON");
@@ -486,7 +490,7 @@
         }
 
         if (mUpdateRotation) {
-            if (DEBUG_ORIENTATION) Slog.d(TAG,
+            if (DEBUG_ORIENTATION) Slog.d(TAG_WM,
                     "Performing post-rotate rotation");
             if (mService.updateRotationUncheckedLocked(false)) {
                 mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
@@ -540,7 +544,7 @@
 
         mService.scheduleAnimationLocked();
 
-        if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
+        if (DEBUG_WINDOW_TRACE) Slog.e(TAG_WM,
                 "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
     }
 
@@ -584,7 +588,7 @@
             do {
                 repeats++;
                 if (repeats > 6) {
-                    Slog.w(TAG, "Animation repeat aborted after too many iterations");
+                    Slog.w(TAG_WM, "Animation repeat aborted after too many iterations");
                     displayContent.layoutNeeded = false;
                     break;
                 }
@@ -600,7 +604,7 @@
 
                 if (isDefaultDisplay
                         && (displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
-                    if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
+                    if (DEBUG_LAYOUT) Slog.v(TAG_WM, "Computing new config from layout");
                     if (mService.updateOrientationFromAppTokensLocked(true)) {
                         displayContent.layoutNeeded = true;
                         mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
@@ -616,7 +620,7 @@
                     performLayoutLockedInner(displayContent, repeats == 1,
                             false /* updateInputWindows */);
                 } else {
-                    Slog.w(TAG, "Layout repeat skipped after too many iterations");
+                    Slog.w(TAG_WM, "Layout repeat skipped after too many iterations");
                 }
 
                 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
@@ -702,7 +706,7 @@
                     }
                 }
 
-                //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
+                //Slog.i(TAG_WM, "Window " + this + " clearing mContentChanged - done placing");
                 w.mContentChanged = false;
 
                 // Moved from updateWindowsAndWallpaperLocked().
@@ -724,7 +728,7 @@
                         }
                         if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
                             if (DEBUG_WALLPAPER_LIGHT)
-                                Slog.v(TAG, "First draw done in potential wallpaper target " + w);
+                                Slog.v(TAG_WM, "First draw done in potential wallpaper target " + w);
                             mWallpaperMayChange = true;
                             displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
                             if (DEBUG_LAYOUT_REPEATS) {
@@ -745,7 +749,7 @@
 
                 final AppWindowToken atoken = w.mAppToken;
                 if (DEBUG_STARTING_WINDOW && atoken != null && w == atoken.startingWindow) {
-                    Slog.d(TAG, "updateWindows: starting " + w
+                    Slog.d(TAG_WM, "updateWindows: starting " + w
                             + " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
                             + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
                 }
@@ -759,11 +763,11 @@
                             || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
                             && !w.mExiting && !w.mDestroying) {
                         if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
-                            Slog.v(TAG, "Eval win " + w + ": isDrawn="
+                            Slog.v(TAG_WM, "Eval win " + w + ": isDrawn="
                                     + w.isDrawnLw()
                                     + ", isAnimating=" + winAnimator.isAnimating());
                             if (!w.isDrawnLw()) {
-                                Slog.v(TAG, "Not displayed: s="
+                                Slog.v(TAG_WM, "Not displayed: s="
                                         + winAnimator.mSurfaceController
                                         + " pv=" + w.mPolicyVisibility
                                         + " mDrawState=" + winAnimator.drawStateToString()
@@ -778,7 +782,7 @@
                                 if (w.isDrawnLw()) {
                                     atoken.numDrawnWindows++;
                                     if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
-                                        Slog.v(TAG, "tokenMayBeDrawn: " + atoken
+                                        Slog.v(TAG_WM, "tokenMayBeDrawn: " + atoken
                                                 + " freezingScreen="
                                                 + atoken.mAppAnimator.freezingScreen
                                                 + " mAppFreezing=" + w.mAppFreezing);
@@ -846,8 +850,8 @@
         int i;
 
         if (DEBUG_LAYOUT) {
-            Slog.v(TAG, "-------------------------------------");
-            Slog.v(TAG, "performLayout: needed="
+            Slog.v(TAG_WM, "-------------------------------------");
+            Slog.v(TAG_WM, "performLayout: needed="
                     + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
         }
 
@@ -880,18 +884,18 @@
                     || win.isGoneForLayoutLw();
 
             if (DEBUG_LAYOUT && !win.mLayoutAttached) {
-                Slog.v(TAG, "1ST PASS " + win
+                Slog.v(TAG_WM, "1ST PASS " + win
                         + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
                         + " mLayoutAttached=" + win.mLayoutAttached
                         + " screen changed=" + win.isConfigChanged());
                 final AppWindowToken atoken = win.mAppToken;
-                if (gone) Slog.v(TAG, "  GONE: mViewVisibility="
+                if (gone) Slog.v(TAG_WM, "  GONE: mViewVisibility="
                         + win.mViewVisibility + " mRelayoutCalled="
                         + win.mRelayoutCalled + " hidden="
                         + win.mRootToken.hidden + " hiddenRequested="
                         + (atoken != null && atoken.hiddenRequested)
                         + " mAttachedHidden=" + win.mAttachedHidden);
-                else Slog.v(TAG, "  VIS: mViewVisibility="
+                else Slog.v(TAG_WM, "  VIS: mViewVisibility="
                         + win.mViewVisibility + " mRelayoutCalled="
                         + win.mRelayoutCalled + " hidden="
                         + win.mRootToken.hidden + " hiddenRequested="
@@ -911,7 +915,7 @@
                             win.mAppToken.layoutConfigChanges)))) {
                 if (!win.mLayoutAttached) {
                     if (initial) {
-                        //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
+                        //Slog.i(TAG_WM, "Window " + this + " clearing mContentChanged - initial");
                         win.mContentChanged = false;
                     }
                     if (win.mAttrs.type == TYPE_DREAM) {
@@ -931,7 +935,7 @@
                         displayContent.mDimLayerController.updateDimLayer(task);
                     }
 
-                    if (DEBUG_LAYOUT) Slog.v(TAG,
+                    if (DEBUG_LAYOUT) Slog.v(TAG_WM,
                             "  LAYOUT: mFrame="
                             + win.mFrame + " mContainingFrame="
                             + win.mContainingFrame + " mDisplayFrame="
@@ -952,7 +956,7 @@
             final WindowState win = windows.get(i);
 
             if (win.mLayoutAttached) {
-                if (DEBUG_LAYOUT) Slog.v(TAG,
+                if (DEBUG_LAYOUT) Slog.v(TAG_WM,
                         "2ND PASS " + win + " mHaveFrame=" + win.mHaveFrame + " mViewVisibility="
                         + win.mViewVisibility + " mRelayoutCalled=" + win.mRelayoutCalled);
                 // If this view is GONE, then skip it -- keep the current
@@ -966,14 +970,14 @@
                 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
                         || !win.mHaveFrame || win.mLayoutNeeded) {
                     if (initial) {
-                        //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
+                        //Slog.i(TAG_WM, "Window " + this + " clearing mContentChanged - initial");
                         win.mContentChanged = false;
                     }
                     win.mLayoutNeeded = false;
                     win.prelayout();
                     mService.mPolicy.layoutWindowLw(win, win.mAttachedWindow);
                     win.mLayoutSeq = seq;
-                    if (DEBUG_LAYOUT) Slog.v(TAG,
+                    if (DEBUG_LAYOUT) Slog.v(TAG_WM,
                             "  LAYOUT: mFrame=" + win.mFrame + " mContainingFrame="
                             + win.mContainingFrame + " mDisplayFrame=" + win.mDisplayFrame);
                 }
@@ -1004,7 +1008,7 @@
         if (!transitionGoodToGo(appsCount)) {
             return 0;
         }
-        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
+        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "**** GOOD TO GO");
         int transit = mService.mAppTransition.getAppTransition();
         if (mService.mSkipAppTransitionAnimation) {
             transit = AppTransition.TRANSIT_UNSET;
@@ -1020,7 +1024,7 @@
 
         // The top-most window will supply the layout params,
         // and we will determine it below.
-        WindowManager.LayoutParams animLp = null;
+        LayoutParams animLp = null;
         int bestAnimLayer = -1;
         boolean fullscreenAnim = false;
         boolean voiceInteraction = false;
@@ -1096,21 +1100,127 @@
         // example, when this transition is being done behind
         // the lock screen.
         if (!mService.mPolicy.allowAppAnimationsLw()) {
-            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
                     "Animations disallowed by keyguard or dream.");
             animLp = null;
         }
 
         processApplicationsAnimatingInPlace(transit);
 
-        AppWindowToken topClosingApp = null;
-        int topClosingLayer = 0;
+        handleClosingApps(transit, animLp, voiceInteraction, mTmpLayerAndToken);
+        final AppWindowToken topClosingApp = mTmpLayerAndToken.token;
+        final int topClosingLayer = mTmpLayerAndToken.layer;
+
+        final AppWindowToken topOpeningApp = handleOpeningApps(transit,
+                animLp, voiceInteraction, topClosingLayer);
+
+        final AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ?  null :
+                topOpeningApp.mAppAnimator;
+        final AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
+                topClosingApp.mAppAnimator;
+
+        mService.mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator);
+        mService.mAppTransition.postAnimationCallback();
+        mService.mAppTransition.clear();
+
+        mService.mOpeningApps.clear();
+        mService.mClosingApps.clear();
+
+        // This has changed the visibility of windows, so perform
+        // a new layout to get them all up-to-date.
+        mService.getDefaultDisplayContentLocked().layoutNeeded = true;
+
+        // TODO(multidisplay): IMEs are only supported on the default display.
+        if (windows == mService.getDefaultWindowListLocked()
+                && !mService.moveInputMethodWindowsIfNeededLocked(true)) {
+            mService.assignLayersLocked(windows);
+        }
+        mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
+                true /*updateInputWindows*/);
+        mService.mFocusMayChange = false;
+        mService.notifyActivityDrawnForKeyguard();
+        return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
+    }
+
+    private AppWindowToken handleOpeningApps(int transit, LayoutParams animLp,
+            boolean voiceInteraction, int topClosingLayer) {
+        AppWindowToken topOpeningApp = null;
+        final int appsCount = mService.mOpeningApps.size();
+        for (int i = 0; i < appsCount; i++) {
+            AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
+            final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
+            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Now opening app" + wtoken);
+
+            if (!appAnimator.usingTransferredAnimation) {
+                appAnimator.clearThumbnail();
+                appAnimator.animation = null;
+            }
+            wtoken.inPendingTransaction = false;
+            if (!mService.setTokenVisibilityLocked(
+                    wtoken, animLp, true, transit, false, voiceInteraction)){
+                // This token isn't going to be animating. Add it to the list of tokens to
+                // be notified of app transition complete since the notification will not be
+                // sent be the app window animator.
+                mService.mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
+            }
+            wtoken.updateReportedVisibilityLocked();
+            wtoken.waitingToShow = false;
+
+            appAnimator.mAllAppWinAnimators.clear();
+            final int windowsCount = wtoken.allAppWindows.size();
+            for (int j = 0; j < windowsCount; j++) {
+                appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
+            }
+            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
+                    ">>> OPEN TRANSACTION handleAppTransitionReadyLocked()");
+            SurfaceControl.openTransaction();
+            try {
+                mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
+            } finally {
+                SurfaceControl.closeTransaction();
+                if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
+                        "<<< CLOSE TRANSACTION handleAppTransitionReadyLocked()");
+            }
+            mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
+
+            int topOpeningLayer = 0;
+            if (animLp != null) {
+                int layer = -1;
+                for (int j = 0; j < wtoken.windows.size(); j++) {
+                    final WindowState win = wtoken.windows.get(j);
+                    // Clearing the mExiting flag before entering animation. It will be set to true
+                    // if app window is removed, or window relayout to invisible. We don't want to
+                    // clear it out for windows that get replaced, because the animation depends on
+                    // the flag to remove the replaced window.
+                    if (win.mAppToken == null || !win.mAppToken.mWillReplaceWindow) {
+                        win.mExiting = false;
+                    }
+                    if (win.mWinAnimator.mAnimLayer > layer) {
+                        layer = win.mWinAnimator.mAnimLayer;
+                    }
+                }
+                if (topOpeningApp == null || layer > topOpeningLayer) {
+                    topOpeningApp = wtoken;
+                    topOpeningLayer = layer;
+                }
+            }
+            if (mService.mAppTransition.isNextAppTransitionThumbnailUp()) {
+                createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
+            }
+
+            wtoken.restoreSavedSurfaces();
+        }
+        return topOpeningApp;
+    }
+
+    private void handleClosingApps(int transit, LayoutParams animLp, boolean voiceInteraction,
+            LayerAndToken layerAndToken) {
+        final int appsCount;
         appsCount = mService.mClosingApps.size();
-        for (i = 0; i < appsCount; i++) {
+        for (int i = 0; i < appsCount; i++) {
             AppWindowToken wtoken = mService.mClosingApps.valueAt(i);
             final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
-            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
-                    "Now closing app " + wtoken);
+            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Now closing app " + wtoken);
             appAnimator.clearThumbnail();
             appAnimator.animation = null;
             wtoken.inPendingTransaction = false;
@@ -1137,122 +1247,32 @@
                         layer = win.mWinAnimator.mAnimLayer;
                     }
                 }
-                if (topClosingApp == null || layer > topClosingLayer) {
-                    topClosingApp = wtoken;
-                    topClosingLayer = layer;
+                if (layerAndToken.token == null || layer > layerAndToken.layer) {
+                    layerAndToken.token = wtoken;
+                    layerAndToken.layer = layer;
                 }
             }
+            if (mService.mAppTransition.isNextAppTransitionThumbnailDown()) {
+                createThumbnailAppAnimator(transit, wtoken, 0, layerAndToken.layer);
+            }
         }
-
-        AppWindowToken topOpeningApp = null;
-        appsCount = mService.mOpeningApps.size();
-        for (i = 0; i < appsCount; i++) {
-            AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
-            final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
-            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
-                    "Now opening app" + wtoken);
-
-            if (!appAnimator.usingTransferredAnimation) {
-                appAnimator.clearThumbnail();
-                appAnimator.animation = null;
-            }
-            wtoken.inPendingTransaction = false;
-            if (!mService.setTokenVisibilityLocked(
-                    wtoken, animLp, true, transit, false, voiceInteraction)){
-                // This token isn't going to be animating. Add it to the list of tokens to
-                // be notified of app transition complete since the notification will not be
-                // sent be the app window animator.
-                mService.mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
-            }
-            wtoken.updateReportedVisibilityLocked();
-            wtoken.waitingToShow = false;
-
-            appAnimator.mAllAppWinAnimators.clear();
-            final int windowsCount = wtoken.allAppWindows.size();
-            for (int j = 0; j < windowsCount; j++) {
-                appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
-            }
-            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
-                    ">>> OPEN TRANSACTION handleAppTransitionReadyLocked()");
-            SurfaceControl.openTransaction();
-            try {
-                mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
-            } finally {
-                SurfaceControl.closeTransaction();
-                if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
-                        "<<< CLOSE TRANSACTION handleAppTransitionReadyLocked()");
-            }
-            mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
-
-            int topOpeningLayer = 0;
-            if (animLp != null) {
-                int layer = -1;
-                for (int j = 0; j < wtoken.windows.size(); j++) {
-                    final WindowState win = wtoken.windows.get(j);
-                    // Clearing the mExiting flag before entering animation. It will be set to true
-                    // if app window is removed, or window relayout to invisible. We don't want to
-                    // clear it out for windows that get replaced, because the animation depends on
-                    // the flag to remove the replaced window.
-                    if (win.mAppToken == null || !win.mAppToken.mWillReplaceWindow) {
-                        win.mExiting = false;
-                    }
-                    if (win.mWinAnimator.mAnimLayer > layer) {
-                        layer = win.mWinAnimator.mAnimLayer;
-                    }
-                }
-                if (topOpeningApp == null || layer > topOpeningLayer) {
-                    topOpeningApp = wtoken;
-                    topOpeningLayer = layer;
-                }
-            }
-            createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
-
-            wtoken.restoreSavedSurfaces();
-        }
-
-        AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ?  null :
-                topOpeningApp.mAppAnimator;
-        AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
-                topClosingApp.mAppAnimator;
-
-        mService.mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator);
-        mService.mAppTransition.postAnimationCallback();
-        mService.mAppTransition.clear();
-
-        mService.mOpeningApps.clear();
-        mService.mClosingApps.clear();
-
-        // This has changed the visibility of windows, so perform
-        // a new layout to get them all up-to-date.
-        mService.getDefaultDisplayContentLocked().layoutNeeded = true;
-
-        // TODO(multidisplay): IMEs are only supported on the default display.
-        if (windows == mService.getDefaultWindowListLocked()
-                && !mService.moveInputMethodWindowsIfNeededLocked(true)) {
-            mService.assignLayersLocked(windows);
-        }
-        mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
-                true /*updateInputWindows*/);
-        mService.mFocusMayChange = false;
-        mService.notifyActivityDrawnForKeyguard();
-        return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
     }
 
     private boolean transitionGoodToGo(int appsCount) {
-        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
                 "Checking " + appsCount + " opening apps (frozen="
                         + mService.mDisplayFrozen + " timeout="
                         + mService.mAppTransition.isTimeout() + ")...");
         if (!mService.mAppTransition.isTimeout()) {
             for (int i = 0; i < appsCount; i++) {
                 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
-                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
                         "Check opening app=" + wtoken + ": allDrawn="
                         + wtoken.allDrawn + " startingDisplayed="
                         + wtoken.startingDisplayed + " startingMoved="
                         + wtoken.startingMoved);
 
-                if (wtoken.mHasSavedSurface || wtoken.mAnimatingWithSavedSurface) {
+                if (wtoken.hasSavedSurface() || wtoken.mAnimatingWithSavedSurface) {
                     continue;
                 }
                 if (!wtoken.allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) {
@@ -1262,7 +1282,7 @@
 
             // We also need to wait for the specs to be fetched, if needed.
             if (mService.mAppTransition.isFetchingAppTransitionsSpecs()) {
-                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "isFetchingAppTransitionSpecs=true");
+                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "isFetchingAppTransitionSpecs=true");
                 return false;
             }
 
@@ -1283,7 +1303,7 @@
                         ? null : wallpaperTarget;
         final ArraySet<AppWindowToken> openingApps = mService.mOpeningApps;
         final ArraySet<AppWindowToken> closingApps = mService.mClosingApps;
-        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
                 "New wallpaper target=" + wallpaperTarget
                         + ", oldWallpaper=" + oldWallpaper
                         + ", lower target=" + lowerWallpaperTarget
@@ -1293,7 +1313,7 @@
         mService.mAnimateWallpaperWithTarget = false;
         if (closingAppHasWallpaper && openingAppHasWallpaper) {
             if (DEBUG_APP_TRANSITIONS)
-                Slog.v(TAG, "Wallpaper animation!");
+                Slog.v(TAG_WM, "Wallpaper animation!");
             switch (transit) {
                 case AppTransition.TRANSIT_ACTIVITY_OPEN:
                 case AppTransition.TRANSIT_TASK_OPEN:
@@ -1306,14 +1326,14 @@
                     transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
                     break;
             }
-            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
                     "New transit: " + AppTransition.appTransitionToString(transit));
         } else if (oldWallpaper != null && !mService.mOpeningApps.isEmpty()
                 && !openingApps.contains(oldWallpaper.mAppToken)
                 && closingApps.contains(oldWallpaper.mAppToken)) {
             // We are transitioning from an activity with a wallpaper to one without.
             transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
-            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
                     "New transit away from wallpaper: "
                     + AppTransition.appTransitionToString(transit));
         } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw() &&
@@ -1321,7 +1341,7 @@
             // We are transitioning from an activity without
             // a wallpaper to now showing the wallpaper
             transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
-            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
                     "New transit into wallpaper: "
                     + AppTransition.appTransitionToString(transit));
         } else {
@@ -1335,7 +1355,7 @@
      * @param dispInfo info of the display that the window's obscuring state is checked against.
      */
     private void handleNotObscuredLocked(final WindowState w, final DisplayInfo dispInfo) {
-        final WindowManager.LayoutParams attrs = w.mAttrs;
+        final LayoutParams attrs = w.mAttrs;
         final int attrFlags = attrs.flags;
         final boolean canBeSeen = w.isDisplayedLw();
 
@@ -1416,7 +1436,7 @@
                         int numInteresting = wtoken.numInterestingWindows;
                         if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
                             if (DEBUG_VISIBILITY)
-                                Slog.v(TAG, "allDrawn: " + wtoken
+                                Slog.v(TAG_WM, "allDrawn: " + wtoken
                                     + " interesting=" + numInteresting
                                     + " drawn=" + wtoken.numDrawnWindows);
                             wtoken.allDrawn = true;
@@ -1445,7 +1465,7 @@
                 final AppWindowToken wtoken = win.mAppToken;
                 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
                 if (DEBUG_APP_TRANSITIONS)
-                    Slog.v(TAG, "Now animating app in place " + wtoken);
+                    Slog.v(TAG_WM, "Now animating app in place " + wtoken);
                 appAnimator.clearThumbnail();
                 appAnimator.animation = null;
                 mService.updateTokenInPlaceLocked(wtoken, transit);
@@ -1471,7 +1491,7 @@
         final int taskId = appToken.mTask.mTaskId;
         Bitmap thumbnailHeader = mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
         if (thumbnailHeader == null || thumbnailHeader.getConfig() == Bitmap.Config.ALPHA_8) {
-            if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
+            if (DEBUG_APP_TRANSITIONS) Slog.d(TAG_WM, "No thumbnail header bitmap for: " + taskId);
             return;
         }
         // This thumbnail animation is very special, we need to have
@@ -1489,7 +1509,7 @@
                     PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
             surfaceControl.setLayerStack(display.getLayerStack());
             if (SHOW_TRANSACTIONS) {
-                Slog.i(TAG, "  THUMBNAIL " + surfaceControl + ": CREATE");
+                Slog.i(TAG_WM, "  THUMBNAIL " + surfaceControl + ": CREATE");
             }
 
             // Draw the thumbnail onto the surface
@@ -1532,7 +1552,7 @@
             openingAppAnimator.thumbnailX = mTmpStartRect.left;
             openingAppAnimator.thumbnailY = mTmpStartRect.top;
         } catch (Surface.OutOfResourcesException e) {
-            Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w="
+            Slog.e(TAG_WM, "Can't allocate thumbnail/Canvas surface w="
                     + dirty.width() + " h=" + dirty.height(), e);
             openingAppAnimator.clearThumbnail();
         }
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 4ac9135..7894ccf 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -16,6 +16,9 @@
 
 package com.android.server.wm;
 
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
 import android.os.IBinder;
 import android.util.Slog;
 
@@ -77,8 +80,7 @@
     void removeAllWindows() {
         for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
             WindowState win = windows.get(winNdx);
-            if (WindowManagerService.DEBUG_WINDOW_MOVEMENT) Slog.w(WindowManagerService.TAG,
-                    "removeAllWindows: removing win=" + win);
+            if (DEBUG_WINDOW_MOVEMENT) Slog.w(TAG_WM, "removeAllWindows: removing win=" + win);
             win.mService.removeWindowLocked(win);
         }
         windows.clear();
@@ -106,4 +108,4 @@
         }
         return stringName;
     }
-}
\ No newline at end of file
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index eed5419..c540e05 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -109,8 +109,6 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
-import android.util.PrintWriterPrinter;
-import android.util.Printer;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.Xml;
@@ -1752,11 +1750,7 @@
 
         try {
             return new DeviceAdminInfo(mContext, ri);
-        } catch (XmlPullParserException e) {
-            Slog.w(LOG_TAG, "Bad device admin requested for user=" + userHandle + ": " + adminName,
-                    e);
-            return null;
-        } catch (IOException e) {
+        } catch (XmlPullParserException | IOException e) {
             Slog.w(LOG_TAG, "Bad device admin requested for user=" + userHandle + ": " + adminName,
                     e);
             return null;
@@ -1994,18 +1988,11 @@
                     XmlUtils.skipCurrentTag(parser);
                 }
             }
-        } catch (NullPointerException e) {
-            Slog.w(LOG_TAG, "failed parsing " + file + " " + e);
-        } catch (NumberFormatException e) {
-            Slog.w(LOG_TAG, "failed parsing " + file + " " + e);
-        } catch (XmlPullParserException e) {
-            Slog.w(LOG_TAG, "failed parsing " + file + " " + e);
         } catch (FileNotFoundException e) {
             // Don't be noisy, this is normal if we haven't defined any policies.
-        } catch (IOException e) {
-            Slog.w(LOG_TAG, "failed parsing " + file + " " + e);
-        } catch (IndexOutOfBoundsException e) {
-            Slog.w(LOG_TAG, "failed parsing " + file + " " + e);
+        } catch (NullPointerException | NumberFormatException | XmlPullParserException | IOException
+                | IndexOutOfBoundsException e) {
+            Slog.w(LOG_TAG, "failed parsing " + file, e);
         }
         try {
             if (stream != null) {
@@ -3541,6 +3528,18 @@
         }
     }
 
+    private void enforceCanManageInstalledKeys(ComponentName who) {
+        if (who == null) {
+            if (!isCallerDelegatedCertInstaller()) {
+                throw new SecurityException("who == null, but caller is not cert installer");
+            }
+        } else {
+            synchronized (this) {
+                getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+            }
+        }
+    }
+
     private boolean isCallerDelegatedCertInstaller() {
         final int callingUid = mInjector.binderGetCallingUid();
         final int userHandle = UserHandle.getUserId(callingUid);
@@ -3630,27 +3629,20 @@
 
     @Override
     public boolean installKeyPair(ComponentName who, byte[] privKey, byte[] cert, String alias) {
-        if (who == null) {
-            if (!isCallerDelegatedCertInstaller()) {
-                throw new SecurityException("who == null, but caller is not cert installer");
-            }
-        } else {
-            synchronized (this) {
-                getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
-            }
-        }
+        enforceCanManageInstalledKeys(who);
+
         final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());
         final long id = mInjector.binderClearCallingIdentity();
         try {
-          final KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext, userHandle);
-          try {
-              IKeyChainService keyChain = keyChainConnection.getService();
-              return keyChain.installKeyPair(privKey, cert, alias);
-          } catch (RemoteException e) {
-              Log.e(LOG_TAG, "Installing certificate", e);
-          } finally {
-              keyChainConnection.close();
-          }
+            final KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext, userHandle);
+            try {
+                IKeyChainService keyChain = keyChainConnection.getService();
+                return keyChain.installKeyPair(privKey, cert, alias);
+            } catch (RemoteException e) {
+                Log.e(LOG_TAG, "Installing certificate", e);
+            } finally {
+                keyChainConnection.close();
+            }
         } catch (InterruptedException e) {
             Log.w(LOG_TAG, "Interrupted while installing certificate", e);
             Thread.currentThread().interrupt();
@@ -3661,6 +3653,31 @@
     }
 
     @Override
+    public boolean removeKeyPair(ComponentName who, String alias) {
+        enforceCanManageInstalledKeys(who);
+
+        final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());
+        final long id = Binder.clearCallingIdentity();
+        try {
+            final KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext, userHandle);
+            try {
+                IKeyChainService keyChain = keyChainConnection.getService();
+                return keyChain.removeKeyPair(alias);
+            } catch (RemoteException e) {
+                Log.e(LOG_TAG, "Removing keypair", e);
+            } finally {
+                keyChainConnection.close();
+            }
+        } catch (InterruptedException e) {
+            Log.w(LOG_TAG, "Interrupted while removing keypair", e);
+            Thread.currentThread().interrupt();
+        } finally {
+            Binder.restoreCallingIdentity(id);
+        }
+        return false;
+    }
+
+    @Override
     public void choosePrivateKeyAlias(final int uid, final Uri uri, final String alias,
             final IBinder response) {
         // Caller UID needs to be trusted, so we restrict this method to SYSTEM_UID callers.
@@ -5777,7 +5794,7 @@
                     throw new SecurityException("Device owner cannot set user restriction " + key);
                 }
             } else { // profile owner
-                if (!UserRestrictionsUtils.canProfileOwnerChange(key)) {
+                if (!UserRestrictionsUtils.canProfileOwnerChange(key, userHandle)) {
                     throw new SecurityException("Profile owner cannot set user restriction " + key);
                 }
             }
diff --git a/services/net/java/android/net/dhcp/DhcpClient.java b/services/net/java/android/net/dhcp/DhcpClient.java
index e7e99c4..2329b42 100644
--- a/services/net/java/android/net/dhcp/DhcpClient.java
+++ b/services/net/java/android/net/dhcp/DhcpClient.java
@@ -20,8 +20,8 @@
 import com.android.internal.util.Protocol;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
+import com.android.internal.util.WakeupMessage;
 
-import android.app.AlarmManager;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -128,7 +128,6 @@
 
     // System services / libraries we use.
     private final Context mContext;
-    private final AlarmManager mAlarmManager;
     private final Random mRandom;
     private final INetworkManagementService mNMService;
 
@@ -143,10 +142,10 @@
 
     // State variables.
     private final StateMachine mController;
-    private final AlarmListener mKickAlarm;
-    private final AlarmListener mTimeoutAlarm;
-    private final AlarmListener mRenewAlarm;
-    private final AlarmListener mOneshotTimeoutAlarm;
+    private final WakeupMessage mKickAlarm;
+    private final WakeupMessage mTimeoutAlarm;
+    private final WakeupMessage mRenewAlarm;
+    private final WakeupMessage mOneshotTimeoutAlarm;
     private final String mIfaceName;
 
     private boolean mRegisteredForPreDhcpNotification;
@@ -174,6 +173,11 @@
     private State mWaitBeforeStartState = new WaitBeforeStartState(mDhcpInitState);
     private State mWaitBeforeRenewalState = new WaitBeforeRenewalState(mDhcpRenewingState);
 
+    private WakeupMessage makeWakeupMessage(String cmdName, int cmd) {
+        cmdName = DhcpClient.class.getSimpleName() + "." + mIfaceName + "." + cmdName;
+        return new WakeupMessage(mContext, getHandler(), cmdName, cmd);
+    }
+
     private DhcpClient(Context context, StateMachine controller, String iface) {
         super(TAG);
 
@@ -197,22 +201,21 @@
 
         setInitialState(mStoppedState);
 
-        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
         IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
         mNMService = INetworkManagementService.Stub.asInterface(b);
 
         mRandom = new Random();
 
         // Used to schedule packet retransmissions.
-        mKickAlarm = new AlarmListener("KICK", CMD_KICK);
+        mKickAlarm = makeWakeupMessage("KICK", CMD_KICK);
         // Used to time out PacketRetransmittingStates.
-        mTimeoutAlarm = new AlarmListener("TIMEOUT", CMD_TIMEOUT);
+        mTimeoutAlarm = makeWakeupMessage("TIMEOUT", CMD_TIMEOUT);
         // Used to schedule DHCP renews.
-        mRenewAlarm = new AlarmListener("RENEW", DhcpStateMachine.CMD_RENEW_DHCP);
+        mRenewAlarm = makeWakeupMessage("RENEW", DhcpStateMachine.CMD_RENEW_DHCP);
         // Used to tell the caller when its request (CMD_START_DHCP or CMD_RENEW_DHCP) timed out.
         // TODO: when the legacy DHCP client is gone, make the client fully asynchronous and
         // remove this.
-        mOneshotTimeoutAlarm = new AlarmListener("ONESHOT_TIMEOUT", CMD_ONESHOT_TIMEOUT);
+        mOneshotTimeoutAlarm = makeWakeupMessage("ONESHOT_TIMEOUT", CMD_ONESHOT_TIMEOUT);
     }
 
     @Override
@@ -227,32 +230,6 @@
         return client;
     }
 
-    /**
-     * An AlarmListener that sends the specified command to the state machine.
-     */
-    private class AlarmListener implements AlarmManager.OnAlarmListener {
-        private final int cmd;
-        private final String name;
-
-        public AlarmListener(final String cmdName, final int cmd) {
-            this.cmd = cmd;
-            this.name = DhcpClient.class.getSimpleName() + "." + mIfaceName + "." + cmdName;
-        }
-
-        public void set(long alarmTime) {
-            mAlarmManager.setExact(
-                    AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmTime, name, this, getHandler());
-        }
-
-        public void cancel() {
-            mAlarmManager.cancel(this);
-        }
-
-        public void onAlarm() {
-            sendMessage(cmd);
-        }
-    }
-
     private boolean initInterface() {
         try {
             mIface = NetworkInterface.getByName(mIfaceName);
@@ -412,11 +389,10 @@
     }
 
     private void scheduleRenew() {
-        mAlarmManager.cancel(mRenewAlarm);
         if (mDhcpLeaseExpiry != 0) {
             long now = SystemClock.elapsedRealtime();
             long alarmTime = (now + mDhcpLeaseExpiry) / 2;
-            mRenewAlarm.set(alarmTime);
+            mRenewAlarm.schedule(alarmTime);
             Log.d(TAG, "Scheduling renewal in " + ((alarmTime - now) / 1000) + "s");
         } else {
             Log.d(TAG, "Infinite lease, no renewal needed");
@@ -548,7 +524,7 @@
     // one state, so we can just use the state timeout.
     private void scheduleOneshotTimeout() {
         final long alarmTime = SystemClock.elapsedRealtime() + DHCP_TIMEOUT_MS;
-        mOneshotTimeoutAlarm.set(alarmTime);
+        mOneshotTimeoutAlarm.schedule(alarmTime);
     }
 
     class StoppedState extends LoggingState {
@@ -713,8 +689,7 @@
             long now = SystemClock.elapsedRealtime();
             long timeout = jitterTimer(mTimer);
             long alarmTime = now + timeout;
-            mKickAlarm.cancel();
-            mKickAlarm.set(alarmTime);
+            mKickAlarm.schedule(alarmTime);
             mTimer *= 2;
             if (mTimer > MAX_TIMEOUT_MS) {
                 mTimer = MAX_TIMEOUT_MS;
@@ -724,7 +699,7 @@
         protected void maybeInitTimeout() {
             if (mTimeout > 0) {
                 long alarmTime = SystemClock.elapsedRealtime() + mTimeout;
-                mTimeoutAlarm.set(alarmTime);
+                mTimeoutAlarm.schedule(alarmTime);
             }
         }
     }
@@ -846,6 +821,11 @@
                     return NOT_HANDLED;
             }
         }
+
+        @Override
+        public void exit() {
+            mRenewAlarm.cancel();
+        }
     }
 
     class DhcpRenewingState extends PacketRetransmittingState {
diff --git a/services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java b/services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java
index 757f1c6..13657ab 100644
--- a/services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java
+++ b/services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java
@@ -21,6 +21,7 @@
 import android.content.ContextWrapper;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.UserHandle;
 
@@ -165,6 +166,11 @@
     }
 
     @Override
+    public void sendStickyBroadcastAsUser(Intent intent, UserHandle user, Bundle options) {
+        sendBroadcast(intent);
+    }
+
+    @Override
     public void removeStickyBroadcast(Intent intent) {
         // ignored
     }
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
index 9e70138..48a11c5 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
@@ -16,9 +16,12 @@
 
 package com.android.server.pm;
 
+import android.content.pm.UserInfo;
 import android.os.Bundle;
 import android.os.FileUtils;
 import android.os.Parcelable;
+import android.os.UserHandle;
+import android.os.UserManager;
 import android.test.AndroidTestCase;
 import android.util.AtomicFile;
 
@@ -29,6 +32,7 @@
 public class UserManagerServiceTest extends AndroidTestCase {
     private static String[] STRING_ARRAY = new String[] {"<tag", "<![CDATA["};
     private File restrictionsFile;
+    private int tempUserId = UserHandle.USER_NULL;
 
     @Override
     protected void setUp() throws Exception {
@@ -40,6 +44,9 @@
     @Override
     protected void tearDown() throws Exception {
         restrictionsFile.delete();
+        if (tempUserId != UserHandle.USER_NULL) {
+            UserManager.get(mContext).removeUser(tempUserId);
+        }
         super.tearDown();
     }
 
@@ -55,6 +62,16 @@
         assertBundle(bundle);
     }
 
+    public void testAddUserWithAccount() {
+        UserManager um = UserManager.get(mContext);
+        UserInfo user = um.createUser("Test User", 0);
+        assertNotNull(user);
+        tempUserId = user.id;
+        String accountName = "Test Account";
+        um.setUserAccount(tempUserId, accountName);
+        assertEquals(accountName, um.getUserAccount(tempUserId));
+    }
+
     private Bundle createBundle() {
         Bundle result = new Bundle();
         // Tests for 6 allowed types: Integer, Boolean, String, String[], Bundle and Parcelable[]
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
index 5542a4f..5bdf6f7 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.pm;
 
+import android.os.UserHandle;
 import com.android.server.devicepolicy.DpmTestUtils;
 
 import android.os.Bundle;
@@ -87,10 +88,25 @@
     }
 
     public void testCanProfileOwnerChange() {
-        assertFalse(UserRestrictionsUtils.canProfileOwnerChange(UserManager.DISALLOW_RECORD_AUDIO));
-        assertFalse(UserRestrictionsUtils.canProfileOwnerChange(UserManager.DISALLOW_WALLPAPER));
-        assertFalse(UserRestrictionsUtils.canProfileOwnerChange(UserManager.DISALLOW_ADD_USER));
-        assertTrue(UserRestrictionsUtils.canProfileOwnerChange(UserManager.DISALLOW_ADJUST_VOLUME));
+        int user = UserHandle.USER_SYSTEM;
+        assertFalse(UserRestrictionsUtils.canProfileOwnerChange(
+                UserManager.DISALLOW_RECORD_AUDIO, user));
+        assertFalse(UserRestrictionsUtils.canProfileOwnerChange(
+                UserManager.DISALLOW_WALLPAPER, user));
+        assertTrue(UserRestrictionsUtils.canProfileOwnerChange(
+                UserManager.DISALLOW_ADD_USER, user));
+        assertTrue(UserRestrictionsUtils.canProfileOwnerChange(
+                UserManager.DISALLOW_ADJUST_VOLUME, user));
+
+        user = 10;
+        assertFalse(UserRestrictionsUtils.canProfileOwnerChange(
+                UserManager.DISALLOW_RECORD_AUDIO, user));
+        assertFalse(UserRestrictionsUtils.canProfileOwnerChange(
+                UserManager.DISALLOW_WALLPAPER, user));
+        assertFalse(UserRestrictionsUtils.canProfileOwnerChange(
+                UserManager.DISALLOW_ADD_USER, user));
+        assertTrue(UserRestrictionsUtils.canProfileOwnerChange(
+                UserManager.DISALLOW_ADJUST_VOLUME, user));
     }
 
     public void testSortToGlobalAndLocal() {
diff --git a/services/usb/java/com/android/server/usb/UsbSettingsManager.java b/services/usb/java/com/android/server/usb/UsbSettingsManager.java
index 4786d11..7976cb8 100644
--- a/services/usb/java/com/android/server/usb/UsbSettingsManager.java
+++ b/services/usb/java/com/android/server/usb/UsbSettingsManager.java
@@ -52,12 +52,10 @@
 import org.xmlpull.v1.XmlSerializer;
 
 import java.io.File;
-import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.PrintWriter;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -984,14 +982,7 @@
     public boolean hasPermission(UsbDevice device) {
         synchronized (mLock) {
             int uid = Binder.getCallingUid();
-            int androidMediaUid;
-            try {
-                androidMediaUid = mPackageManager.getApplicationInfo("com.android.mtp", 0).uid;
-            } catch (NameNotFoundException e) {
-                androidMediaUid = -1;
-            }
-            if (uid == Process.SYSTEM_UID || UserHandle.getAppId(uid) == androidMediaUid ||
-                    mDisablePermissionDialogs) {
+            if (uid == Process.SYSTEM_UID || mDisablePermissionDialogs) {
                 return true;
             }
             SparseBooleanArray uidList = mDevicePermissionMap.get(device.getDeviceName());
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 109d214..3efd0fb 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -266,8 +266,6 @@
         pw.print("  Session service="); pw.println(mInfo.getSessionService());
         pw.println("  Service info:");
         mInfo.getServiceInfo().dump(new PrintWriterPrinter(pw), "    ");
-        pw.println("  Application info:");
-        mInfo.getServiceInfo().applicationInfo.dump(new PrintWriterPrinter(pw), "    ");
         pw.print("  Recognition service="); pw.println(mInfo.getRecognitionService());
         pw.print("  Settings activity="); pw.println(mInfo.getSettingsActivity());
         pw.print("  Supports assist="); pw.println(mInfo.getSupportsAssist());
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index b5b4e5f..9eb1665 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -247,6 +247,14 @@
             "android.telecom.extra.CONNECTION_SERVICE";
 
     /**
+     * Optional extra for communicating the call technology used by a
+     * {@link com.android.internal.telephony.Connection} to Telecom
+     * @hide
+     */
+    public static final String EXTRA_CALL_TECHNOLOGY_TYPE =
+            "android.telecom.extra.CALL_TECHNOLOGY_TYPE";
+
+    /**
      * An optional {@link android.content.Intent#ACTION_CALL} intent extra denoting the
      * package name of the app specifying an alternative gateway for the call.
      * The value is a string.
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index c7f3d0a..6ffc026 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -385,6 +385,11 @@
     public static final String KEY_VVM_TYPE_STRING = "vvm_type_string";
 
     /**
+     * Whether cellular data is required to access visual voicemail.
+     */
+    public static final String KEY_VVM_CELLULAR_DATA_REQUIRED_BOOLEAN = "vvm_cellular_data_required";
+
+    /**
      * The package name of the carrier's visual voicemail app to ensure that dialer visual voicemail
      * and carrier visual voicemail are not active at the same time.
      */
@@ -599,6 +604,7 @@
         sDefaults.putString(KEY_VVM_DESTINATION_NUMBER_STRING, "");
         sDefaults.putInt(KEY_VVM_PORT_NUMBER_INT, 0);
         sDefaults.putString(KEY_VVM_TYPE_STRING, "");
+        sDefaults.putBoolean(KEY_VVM_CELLULAR_DATA_REQUIRED_BOOLEAN,false);
         sDefaults.putString(KEY_CARRIER_VVM_PACKAGE_NAME_STRING, "");
         sDefaults.putBoolean(KEY_CI_ACTION_ON_SYS_UPDATE_BOOL, false);
         sDefaults.putString(KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING, "");
@@ -673,12 +679,15 @@
     @Nullable
     public PersistableBundle getConfigForSubId(int subId) {
         try {
-            return getICarrierConfigLoader().getConfigForSubId(subId);
+            ICarrierConfigLoader loader = getICarrierConfigLoader();
+            if (loader == null) {
+                Rlog.w(TAG, "Error getting config for subId " + subId
+                        + " ICarrierConfigLoader is null");
+                return null;
+            }
+            return loader.getConfigForSubId(subId);
         } catch (RemoteException ex) {
-            Rlog.e(TAG, "Error getting config for subId " + Integer.toString(subId) + ": "
-                    + ex.toString());
-        } catch (NullPointerException ex) {
-            Rlog.e(TAG, "Error getting config for subId " + Integer.toString(subId) + ": "
+            Rlog.e(TAG, "Error getting config for subId " + subId + ": "
                     + ex.toString());
         }
         return null;
@@ -714,11 +723,15 @@
      */
     public void notifyConfigChangedForSubId(int subId) {
         try {
-            getICarrierConfigLoader().notifyConfigChangedForSubId(subId);
+            ICarrierConfigLoader loader = getICarrierConfigLoader();
+            if (loader == null) {
+                Rlog.w(TAG, "Error reloading config for subId=" + subId
+                        + " ICarrierConfigLoader is null");
+                return;
+            }
+            loader.notifyConfigChangedForSubId(subId);
         } catch (RemoteException ex) {
             Rlog.e(TAG, "Error reloading config for subId=" + subId + ": " + ex.toString());
-        } catch (NullPointerException ex) {
-            Rlog.e(TAG, "Error reloading config for subId=" + subId + ": " + ex.toString());
         }
     }
 
@@ -734,11 +747,15 @@
     @SystemApi
     public void updateConfigForPhoneId(int phoneId, String simState) {
         try {
-            getICarrierConfigLoader().updateConfigForPhoneId(phoneId, simState);
+            ICarrierConfigLoader loader = getICarrierConfigLoader();
+            if (loader == null) {
+                Rlog.w(TAG, "Error updating config for phoneId=" + phoneId
+                        + " ICarrierConfigLoader is null");
+                return;
+            }
+            loader.updateConfigForPhoneId(phoneId, simState);
         } catch (RemoteException ex) {
             Rlog.e(TAG, "Error updating config for phoneId=" + phoneId + ": " + ex.toString());
-        } catch (NullPointerException ex) {
-            Rlog.e(TAG, "Error updating config for phoneId=" + phoneId + ": " + ex.toString());
         }
     }
 
@@ -754,6 +771,7 @@
     }
 
     /** @hide */
+    @Nullable
     private ICarrierConfigLoader getICarrierConfigLoader() {
         return ICarrierConfigLoader.Stub
                 .asInterface(ServiceManager.getService(Context.CARRIER_CONFIG_SERVICE));
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index c967c2b..64d2978 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -130,12 +130,6 @@
         throw new UnsupportedOperationException();
     }
 
-    /** @hide */
-    @Override
-    public File getSharedPrefsFile(String name) {
-        throw new UnsupportedOperationException();
-    }
-
     @Override
     public String getPackageCodePath() {
         throw new UnsupportedOperationException();
@@ -172,6 +166,11 @@
     }
 
     @Override
+    public File getSharedPreferencesPath(String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public String[] fileList() {
         throw new UnsupportedOperationException();
     }
@@ -182,18 +181,6 @@
     }
 
     @Override
-    public File getDeviceEncryptedFilesDir() {
-        throw new UnsupportedOperationException();
-    }
-
-    /** {@hide} */
-    @SystemApi
-    @Override
-    public File getCredentialEncryptedFilesDir() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
     public File getNoBackupFilesDir() {
         throw new UnsupportedOperationException();
     }
@@ -446,6 +433,12 @@
         throw new UnsupportedOperationException();
     }
 
+    /** @hide */
+    @Override
+    public void sendStickyBroadcastAsUser(Intent intent, UserHandle user, Bundle options) {
+        throw new UnsupportedOperationException();
+    }
+
     @Override
     public void sendStickyOrderedBroadcastAsUser(Intent intent,
             UserHandle user, BroadcastReceiver resultReceiver,
@@ -706,4 +699,28 @@
     public File[] getExternalMediaDirs() {
         throw new UnsupportedOperationException();
     }
+
+    @Override
+    public Context createDeviceEncryptedStorageContext() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @SystemApi
+    @Override
+    public Context createCredentialEncryptedStorageContext() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isDeviceEncryptedStorage() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @SystemApi
+    @Override
+    public boolean isCredentialEncryptedStorage() {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 17c24af..f7c63d1 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -16,6 +16,7 @@
 
 package android.test.mock;
 
+import android.annotation.NonNull;
 import android.app.PackageInstallObserver;
 import android.content.ComponentName;
 import android.content.Intent;
@@ -24,6 +25,7 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ContainerEncryptionParams;
+import android.content.pm.EphemeralApplicationInfo;
 import android.content.pm.FeatureInfo;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageDeleteObserver;
@@ -286,6 +288,38 @@
         throw new UnsupportedOperationException();
     }
 
+    /** @hide */
+    @Override
+    public List<EphemeralApplicationInfo> getEphemeralApplications() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public Drawable getEphemeralApplicationIcon(String packageName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public byte[] getEphemeralCookie() {
+        return new byte[0];
+    }
+
+    @Override
+    public boolean isEphemeralApplication() {
+        return false;
+    }
+
+    @Override
+    public int getEphemeralCookieMaxSizeBytes() {
+        return 0;
+    }
+
+    @Override
+    public boolean setEphemeralCookie(@NonNull byte[] cookie) {
+        return false;
+    }
+
     @Override
     public ResolveInfo resolveActivity(Intent intent, int flags) {
         throw new UnsupportedOperationException();
diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java
index 69b2a9d..0c36063 100644
--- a/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java
+++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestCertificateSource.java
@@ -44,4 +44,12 @@
         }
         return anchor.getTrustedCert();
     }
+
+    public X509Certificate findByIssuerAndSignature(X509Certificate cert) {
+        java.security.cert.TrustAnchor anchor = mIndex.findByIssuerAndSignature(cert);
+        if (anchor == null) {
+            return null;
+        }
+        return anchor.getTrustedCert();
+    }
 }
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index c29bb48..c449550 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -127,6 +127,12 @@
     const android::String8& getPlatformBuildVersionName() { return mPlatformVersionName; }
     void setPlatformBuildVersionName(const android::String8& name) { mPlatformVersionName = name; }
 
+    const android::String8& getPrivateSymbolsPackage() const { return mPrivateSymbolsPackage; }
+
+    void setPrivateSymbolsPackage(const android::String8& package) {
+        mPrivateSymbolsPackage = package;
+    }
+
     bool getUTF16StringsOption() {
         return mWantUTF16 || !isMinSdkAtLeast(SDK_FROYO);
     }
@@ -333,6 +339,7 @@
     bool        mBuildAppAsSharedLibrary;
     android::String8 mPlatformVersionCode;
     android::String8 mPlatformVersionName;
+    android::String8 mPrivateSymbolsPackage;
 
     /* file specification */
     int         mArgc;
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 21f47bc2..0bb88a7 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -383,6 +383,16 @@
     }
 }
 
+static void printUsesPermissionSdk23(const String8& name, int maxSdkVersion=-1) {
+    printf("uses-permission-sdk-23: ");
+
+    printf("name='%s'", ResTable::normalizeForOutput(name.string()).string());
+    if (maxSdkVersion != -1) {
+        printf(" maxSdkVersion='%d'", maxSdkVersion);
+    }
+    printf("\n");
+}
+
 static void printUsesImpliedPermission(const String8& name, const String8& reason) {
     printf("uses-implied-permission: name='%s' reason='%s'\n",
             ResTable::normalizeForOutput(name.string()).string(),
@@ -463,12 +473,20 @@
  * a pre-requisite or some other reason.
  */
 struct ImpliedFeature {
+    ImpliedFeature() : impliedBySdk23(false) {}
+    ImpliedFeature(const String8& n, bool sdk23) : name(n), impliedBySdk23(sdk23) {}
+
     /**
      * Name of the implied feature.
      */
     String8 name;
 
     /**
+     * Was this implied by a permission from SDK 23 (<uses-permission-sdk-23 />)?
+     */
+    bool impliedBySdk23;
+
+    /**
      * List of human-readable reasons for why this feature was implied.
      */
     SortedVector<String8> reasons;
@@ -497,18 +515,24 @@
 };
 
 static void addImpliedFeature(KeyedVector<String8, ImpliedFeature>* impliedFeatures,
-        const char* name, const char* reason) {
+                              const char* name, const char* reason, bool sdk23) {
     String8 name8(name);
     ssize_t idx = impliedFeatures->indexOfKey(name8);
     if (idx < 0) {
-        idx = impliedFeatures->add(name8, ImpliedFeature());
-        impliedFeatures->editValueAt(idx).name = name8;
+        idx = impliedFeatures->add(name8, ImpliedFeature(name8, sdk23));
     }
-    impliedFeatures->editValueAt(idx).reasons.add(String8(reason));
+
+    ImpliedFeature* feature = &impliedFeatures->editValueAt(idx);
+
+    // A non-sdk 23 implied feature takes precedence.
+    if (feature->impliedBySdk23 && !sdk23) {
+        feature->impliedBySdk23 = false;
+    }
+    feature->reasons.add(String8(reason));
 }
 
-static void printFeatureGroup(const FeatureGroup& grp,
-        const KeyedVector<String8, ImpliedFeature>* impliedFeatures = NULL) {
+static void printFeatureGroupImpl(const FeatureGroup& grp,
+                                  const KeyedVector<String8, ImpliedFeature>* impliedFeatures) {
     printf("feature-group: label='%s'\n", grp.label.string());
 
     if (grp.openGLESVersion > 0) {
@@ -536,9 +560,11 @@
 
         String8 printableFeatureName(ResTable::normalizeForOutput(
                     impliedFeature.name.string()));
-        printf("  uses-feature: name='%s'\n", printableFeatureName.string());
-        printf("  uses-implied-feature: name='%s' reason='",
-                printableFeatureName.string());
+        const char* sdk23Suffix = impliedFeature.impliedBySdk23 ? "-sdk-23" : "";
+
+        printf("  uses-feature%s: name='%s'\n", sdk23Suffix, printableFeatureName.string());
+        printf("  uses-implied-feature%s: name='%s' reason='", sdk23Suffix,
+               printableFeatureName.string());
         const size_t numReasons = impliedFeature.reasons.size();
         for (size_t j = 0; j < numReasons; j++) {
             printf("%s", impliedFeature.reasons[j].string());
@@ -552,6 +578,15 @@
     }
 }
 
+static void printFeatureGroup(const FeatureGroup& grp) {
+    printFeatureGroupImpl(grp, NULL);
+}
+
+static void printDefaultFeatureGroup(const FeatureGroup& grp,
+                                     const KeyedVector<String8, ImpliedFeature>& impliedFeatures) {
+    printFeatureGroupImpl(grp, &impliedFeatures);
+}
+
 static void addParentFeatures(FeatureGroup* grp, const String8& name) {
     if (name == "android.hardware.camera.autofocus" ||
             name == "android.hardware.camera.flash") {
@@ -572,6 +607,72 @@
     }
 }
 
+static void addImpliedFeaturesForPermission(const int targetSdk, const String8& name,
+                                            KeyedVector<String8, ImpliedFeature>* impliedFeatures,
+                                            bool impliedBySdk23Permission) {
+    if (name == "android.permission.CAMERA") {
+        addImpliedFeature(impliedFeatures, "android.hardware.camera",
+                String8::format("requested %s permission", name.string())
+                .string(), impliedBySdk23Permission);
+    } else if (name == "android.permission.ACCESS_FINE_LOCATION") {
+        addImpliedFeature(impliedFeatures, "android.hardware.location.gps",
+                String8::format("requested %s permission", name.string())
+                .string(), impliedBySdk23Permission);
+        addImpliedFeature(impliedFeatures, "android.hardware.location",
+                String8::format("requested %s permission", name.string())
+                .string(), impliedBySdk23Permission);
+    } else if (name == "android.permission.ACCESS_MOCK_LOCATION") {
+        addImpliedFeature(impliedFeatures, "android.hardware.location",
+                String8::format("requested %s permission", name.string())
+                .string(), impliedBySdk23Permission);
+    } else if (name == "android.permission.ACCESS_COARSE_LOCATION") {
+        addImpliedFeature(impliedFeatures, "android.hardware.location.network",
+                String8::format("requested %s permission", name.string())
+                .string(), impliedBySdk23Permission);
+        addImpliedFeature(impliedFeatures, "android.hardware.location",
+                String8::format("requested %s permission", name.string())
+                .string(), impliedBySdk23Permission);
+    } else if (name == "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" ||
+               name == "android.permission.INSTALL_LOCATION_PROVIDER") {
+        addImpliedFeature(impliedFeatures, "android.hardware.location",
+                String8::format("requested %s permission", name.string())
+                .string(), impliedBySdk23Permission);
+    } else if (name == "android.permission.BLUETOOTH" ||
+               name == "android.permission.BLUETOOTH_ADMIN") {
+        if (targetSdk > 4) {
+            addImpliedFeature(impliedFeatures, "android.hardware.bluetooth",
+                    String8::format("requested %s permission", name.string())
+                    .string(), impliedBySdk23Permission);
+            addImpliedFeature(impliedFeatures, "android.hardware.bluetooth",
+                    "targetSdkVersion > 4", impliedBySdk23Permission);
+        }
+    } else if (name == "android.permission.RECORD_AUDIO") {
+        addImpliedFeature(impliedFeatures, "android.hardware.microphone",
+                String8::format("requested %s permission", name.string())
+                .string(), impliedBySdk23Permission);
+    } else if (name == "android.permission.ACCESS_WIFI_STATE" ||
+               name == "android.permission.CHANGE_WIFI_STATE" ||
+               name == "android.permission.CHANGE_WIFI_MULTICAST_STATE") {
+        addImpliedFeature(impliedFeatures, "android.hardware.wifi",
+                String8::format("requested %s permission", name.string())
+                .string(), impliedBySdk23Permission);
+    } else if (name == "android.permission.CALL_PHONE" ||
+               name == "android.permission.CALL_PRIVILEGED" ||
+               name == "android.permission.MODIFY_PHONE_STATE" ||
+               name == "android.permission.PROCESS_OUTGOING_CALLS" ||
+               name == "android.permission.READ_SMS" ||
+               name == "android.permission.RECEIVE_SMS" ||
+               name == "android.permission.RECEIVE_MMS" ||
+               name == "android.permission.RECEIVE_WAP_PUSH" ||
+               name == "android.permission.SEND_SMS" ||
+               name == "android.permission.WRITE_APN_SETTINGS" ||
+               name == "android.permission.WRITE_SMS") {
+        addImpliedFeature(impliedFeatures, "android.hardware.telephony",
+                String8("requested a telephony permission").string(),
+                impliedBySdk23Permission);
+    }
+}
+
 /*
  * Handle the "dump" command, to extract select data from an archive.
  */
@@ -712,7 +813,8 @@
             size_t len;
             ResXMLTree::event_code_t code;
             int depth = 0;
-            while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
+            while ((code=tree.next()) != ResXMLTree::END_DOCUMENT &&
+                    code != ResXMLTree::BAD_DOCUMENT) {
                 if (code == ResXMLTree::END_TAG) {
                     depth--;
                     continue;
@@ -735,25 +837,53 @@
                     }
                     String8 pkg = AaptXml::getAttribute(tree, NULL, "package", NULL);
                     printf("package: %s\n", ResTable::normalizeForOutput(pkg.string()).string());
-                } else if (depth == 2 && tag == "permission") {
-                    String8 error;
-                    String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);
-                    if (error != "") {
-                        fprintf(stderr, "ERROR: %s\n", error.string());
-                        goto bail;
+                } else if (depth == 2) {
+                    if (tag == "permission") {
+                        String8 error;
+                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);
+                        if (error != "") {
+                            fprintf(stderr, "ERROR: %s\n", error.string());
+                            goto bail;
+                        }
+
+                        if (name == "") {
+                            fprintf(stderr, "ERROR: missing 'android:name' for permission\n");
+                            goto bail;
+                        }
+                        printf("permission: %s\n",
+                                ResTable::normalizeForOutput(name.string()).string());
+                    } else if (tag == "uses-permission") {
+                        String8 error;
+                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);
+                        if (error != "") {
+                            fprintf(stderr, "ERROR: %s\n", error.string());
+                            goto bail;
+                        }
+
+                        if (name == "") {
+                            fprintf(stderr, "ERROR: missing 'android:name' for uses-permission\n");
+                            goto bail;
+                        }
+                        printUsesPermission(name,
+                                AaptXml::getIntegerAttribute(tree, REQUIRED_ATTR, 1) == 0,
+                                AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR));
+                    } else if (tag == "uses-permission-sdk-23" || tag == "uses-permission-sdk-m") {
+                        String8 error;
+                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);
+                        if (error != "") {
+                            fprintf(stderr, "ERROR: %s\n", error.string());
+                            goto bail;
+                        }
+
+                        if (name == "") {
+                            fprintf(stderr, "ERROR: missing 'android:name' for "
+                                    "uses-permission-sdk-23\n");
+                            goto bail;
+                        }
+                        printUsesPermissionSdk23(
+                                name,
+                                AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR));
                     }
-                    printf("permission: %s\n",
-                            ResTable::normalizeForOutput(name.string()).string());
-                } else if (depth == 2 && tag == "uses-permission") {
-                    String8 error;
-                    String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);
-                    if (error != "") {
-                        fprintf(stderr, "ERROR: %s\n", error.string());
-                        goto bail;
-                    }
-                    printUsesPermission(name,
-                            AaptXml::getIntegerAttribute(tree, REQUIRED_ATTR, 1) == 0,
-                            AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR));
                 }
             }
         } else if (strcmp("badging", option) == 0) {
@@ -893,7 +1023,8 @@
             Vector<FeatureGroup> featureGroups;
             KeyedVector<String8, ImpliedFeature> impliedFeatures;
 
-            while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
+            while ((code=tree.next()) != ResXMLTree::END_DOCUMENT &&
+                    code != ResXMLTree::BAD_DOCUMENT) {
                 if (code == ResXMLTree::END_TAG) {
                     depth--;
                     if (depth < 2) {
@@ -924,8 +1055,10 @@
                                             ResTable::normalizeForOutput(aName.string()).string());
                                 }
                                 printf(" label='%s' icon='%s'\n",
-                                        ResTable::normalizeForOutput(activityLabel.string()).string(),
-                                        ResTable::normalizeForOutput(activityIcon.string()).string());
+                                       ResTable::normalizeForOutput(activityLabel.string())
+                                                .string(),
+                                       ResTable::normalizeForOutput(activityIcon.string())
+                                                .string());
                             }
                             if (isLeanbackLauncherActivity) {
                                 printf("leanback-launchable-activity:");
@@ -934,9 +1067,12 @@
                                             ResTable::normalizeForOutput(aName.string()).string());
                                 }
                                 printf(" label='%s' icon='%s' banner='%s'\n",
-                                        ResTable::normalizeForOutput(activityLabel.string()).string(),
-                                        ResTable::normalizeForOutput(activityIcon.string()).string(),
-                                        ResTable::normalizeForOutput(activityBanner.string()).string());
+                                       ResTable::normalizeForOutput(activityLabel.string())
+                                                .string(),
+                                       ResTable::normalizeForOutput(activityIcon.string())
+                                                .string(),
+                                       ResTable::normalizeForOutput(activityBanner.string())
+                                                .string());
                             }
                         }
                         if (!hasIntentFilter) {
@@ -964,18 +1100,21 @@
                                 hasLauncher |= catLauncher;
                                 hasCameraActivity |= actCamera;
                                 hasCameraSecureActivity |= actCameraSecure;
-                                hasOtherActivities |= !actMainActivity && !actCamera && !actCameraSecure;
+                                hasOtherActivities |=
+                                        !actMainActivity && !actCamera && !actCameraSecure;
                             } else if (withinReceiver) {
                                 hasWidgetReceivers |= actWidgetReceivers;
                                 hasDeviceAdminReceiver |= (actDeviceAdminEnabled &&
                                         hasBindDeviceAdminPermission);
-                                hasOtherReceivers |= (!actWidgetReceivers && !actDeviceAdminEnabled);
+                                hasOtherReceivers |=
+                                        (!actWidgetReceivers && !actDeviceAdminEnabled);
                             } else if (withinService) {
                                 hasImeService |= actImeService;
                                 hasWallpaperService |= actWallpaperService;
                                 hasAccessibilityService |= (actAccessibilityService &&
                                         hasBindAccessibilityServicePermission);
-                                hasPrintService |= (actPrintService && hasBindPrintServicePermission);
+                                hasPrintService |=
+                                        (actPrintService && hasBindPrintServicePermission);
                                 hasNotificationListenerService |= actNotificationListenerService &&
                                         hasBindNotificationListenerServicePermission;
                                 hasDreamService |= actDreamService && hasBindDreamServicePermission;
@@ -984,7 +1123,8 @@
                                         !actHostApduService && !actOffHostApduService &&
                                         !actNotificationListenerService);
                             } else if (withinProvider) {
-                                hasDocumentsProvider |= actDocumentsProvider && hasRequiredSafAttributes;
+                                hasDocumentsProvider |=
+                                        actDocumentsProvider && hasRequiredSafAttributes;
                             }
                         }
                         withinIntentFilter = false;
@@ -1125,7 +1265,8 @@
                             goto bail;
                         }
 
-                        String8 banner = AaptXml::getResolvedAttribute(res, tree, BANNER_ATTR, &error);
+                        String8 banner = AaptXml::getResolvedAttribute(res, tree, BANNER_ATTR,
+                                                                       &error);
                         if (error != "") {
                             fprintf(stderr, "ERROR getting 'android:banner' attribute: %s\n",
                                     error.string());
@@ -1135,7 +1276,8 @@
                                 ResTable::normalizeForOutput(label.string()).string());
                         printf("icon='%s'", ResTable::normalizeForOutput(icon.string()).string());
                         if (banner != "") {
-                            printf(" banner='%s'", ResTable::normalizeForOutput(banner.string()).string());
+                            printf(" banner='%s'",
+                                   ResTable::normalizeForOutput(banner.string()).string());
                         }
                         printf("\n");
                         if (testOnly != 0) {
@@ -1178,13 +1320,15 @@
                             }
                         }
                     } else if (tag == "uses-sdk") {
-                        int32_t code = AaptXml::getIntegerAttribute(tree, MIN_SDK_VERSION_ATTR, &error);
+                        int32_t code = AaptXml::getIntegerAttribute(tree, MIN_SDK_VERSION_ATTR,
+                                                                    &error);
                         if (error != "") {
                             error = "";
                             String8 name = AaptXml::getResolvedAttribute(res, tree,
                                     MIN_SDK_VERSION_ATTR, &error);
                             if (error != "") {
-                                fprintf(stderr, "ERROR getting 'android:minSdkVersion' attribute: %s\n",
+                                fprintf(stderr,
+                                        "ERROR getting 'android:minSdkVersion' attribute: %s\n",
                                         error.string());
                                 goto bail;
                             }
@@ -1205,7 +1349,8 @@
                             String8 name = AaptXml::getResolvedAttribute(res, tree,
                                     TARGET_SDK_VERSION_ATTR, &error);
                             if (error != "") {
-                                fprintf(stderr, "ERROR getting 'android:targetSdkVersion' attribute: %s\n",
+                                fprintf(stderr,
+                                        "ERROR getting 'android:targetSdkVersion' attribute: %s\n",
                                         error.string());
                                 goto bail;
                             }
@@ -1297,90 +1442,58 @@
                         }
                     } else if (tag == "uses-permission") {
                         String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);
-                        if (name != "" && error == "") {
-                            if (name == "android.permission.CAMERA") {
-                                addImpliedFeature(&impliedFeatures, "android.hardware.camera",
-                                        String8::format("requested %s permission", name.string())
-                                        .string());
-                            } else if (name == "android.permission.ACCESS_FINE_LOCATION") {
-                                addImpliedFeature(&impliedFeatures, "android.hardware.location.gps",
-                                        String8::format("requested %s permission", name.string())
-                                        .string());
-                                addImpliedFeature(&impliedFeatures, "android.hardware.location",
-                                        String8::format("requested %s permission", name.string())
-                                        .string());
-                            } else if (name == "android.permission.ACCESS_MOCK_LOCATION") {
-                                addImpliedFeature(&impliedFeatures, "android.hardware.location",
-                                        String8::format("requested %s permission", name.string())
-                                        .string());
-                            } else if (name == "android.permission.ACCESS_COARSE_LOCATION") {
-                                addImpliedFeature(&impliedFeatures, "android.hardware.location.network",
-                                        String8::format("requested %s permission", name.string())
-                                        .string());
-                                addImpliedFeature(&impliedFeatures, "android.hardware.location",
-                                        String8::format("requested %s permission", name.string())
-                                        .string());
-                            } else if (name == "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" ||
-                                       name == "android.permission.INSTALL_LOCATION_PROVIDER") {
-                                addImpliedFeature(&impliedFeatures, "android.hardware.location",
-                                        String8::format("requested %s permission", name.string())
-                                        .string());
-                            } else if (name == "android.permission.BLUETOOTH" ||
-                                       name == "android.permission.BLUETOOTH_ADMIN") {
-                                if (targetSdk > 4) {
-                                    addImpliedFeature(&impliedFeatures, "android.hardware.bluetooth",
-                                            String8::format("requested %s permission", name.string())
-                                            .string());
-                                    addImpliedFeature(&impliedFeatures, "android.hardware.bluetooth",
-                                            "targetSdkVersion > 4");
-                                }
-                            } else if (name == "android.permission.RECORD_AUDIO") {
-                                addImpliedFeature(&impliedFeatures, "android.hardware.microphone",
-                                        String8::format("requested %s permission", name.string())
-                                        .string());
-                            } else if (name == "android.permission.ACCESS_WIFI_STATE" ||
-                                       name == "android.permission.CHANGE_WIFI_STATE" ||
-                                       name == "android.permission.CHANGE_WIFI_MULTICAST_STATE") {
-                                addImpliedFeature(&impliedFeatures, "android.hardware.wifi",
-                                        String8::format("requested %s permission", name.string())
-                                        .string());
-                            } else if (name == "android.permission.CALL_PHONE" ||
-                                       name == "android.permission.CALL_PRIVILEGED" ||
-                                       name == "android.permission.MODIFY_PHONE_STATE" ||
-                                       name == "android.permission.PROCESS_OUTGOING_CALLS" ||
-                                       name == "android.permission.READ_SMS" ||
-                                       name == "android.permission.RECEIVE_SMS" ||
-                                       name == "android.permission.RECEIVE_MMS" ||
-                                       name == "android.permission.RECEIVE_WAP_PUSH" ||
-                                       name == "android.permission.SEND_SMS" ||
-                                       name == "android.permission.WRITE_APN_SETTINGS" ||
-                                       name == "android.permission.WRITE_SMS") {
-                                addImpliedFeature(&impliedFeatures, "android.hardware.telephony",
-                                        String8("requested a telephony permission").string());
-                            } else if (name == "android.permission.WRITE_EXTERNAL_STORAGE") {
-                                hasWriteExternalStoragePermission = true;
-                            } else if (name == "android.permission.READ_EXTERNAL_STORAGE") {
-                                hasReadExternalStoragePermission = true;
-                            } else if (name == "android.permission.READ_PHONE_STATE") {
-                                hasReadPhoneStatePermission = true;
-                            } else if (name == "android.permission.READ_CONTACTS") {
-                                hasReadContactsPermission = true;
-                            } else if (name == "android.permission.WRITE_CONTACTS") {
-                                hasWriteContactsPermission = true;
-                            } else if (name == "android.permission.READ_CALL_LOG") {
-                                hasReadCallLogPermission = true;
-                            } else if (name == "android.permission.WRITE_CALL_LOG") {
-                                hasWriteCallLogPermission = true;
-                            }
-
-                            printUsesPermission(name,
-                                    AaptXml::getIntegerAttribute(tree, REQUIRED_ATTR, 1) == 0,
-                                    AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR));
-                       } else {
+                        if (error != "") {
                             fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
                                     error.string());
                             goto bail;
                         }
+
+                        if (name == "") {
+                            fprintf(stderr, "ERROR: missing 'android:name' for uses-permission\n");
+                            goto bail;
+                        }
+
+                        addImpliedFeaturesForPermission(targetSdk, name, &impliedFeatures, false);
+
+                        if (name == "android.permission.WRITE_EXTERNAL_STORAGE") {
+                            hasWriteExternalStoragePermission = true;
+                        } else if (name == "android.permission.READ_EXTERNAL_STORAGE") {
+                            hasReadExternalStoragePermission = true;
+                        } else if (name == "android.permission.READ_PHONE_STATE") {
+                            hasReadPhoneStatePermission = true;
+                        } else if (name == "android.permission.READ_CONTACTS") {
+                            hasReadContactsPermission = true;
+                        } else if (name == "android.permission.WRITE_CONTACTS") {
+                            hasWriteContactsPermission = true;
+                        } else if (name == "android.permission.READ_CALL_LOG") {
+                            hasReadCallLogPermission = true;
+                        } else if (name == "android.permission.WRITE_CALL_LOG") {
+                            hasWriteCallLogPermission = true;
+                        }
+
+                        printUsesPermission(name,
+                                AaptXml::getIntegerAttribute(tree, REQUIRED_ATTR, 1) == 0,
+                                AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR));
+
+                    } else if (tag == "uses-permission-sdk-23" || tag == "uses-permission-sdk-m") {
+                        String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);
+                        if (error != "") {
+                            fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
+                                    error.string());
+                            goto bail;
+                        }
+
+                        if (name == "") {
+                            fprintf(stderr, "ERROR: missing 'android:name' for "
+                                    "uses-permission-sdk-23\n");
+                            goto bail;
+                        }
+
+                        addImpliedFeaturesForPermission(targetSdk, name, &impliedFeatures, true);
+
+                        printUsesPermissionSdk23(
+                                name, AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR));
+
                     } else if (tag == "uses-package") {
                         String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);
                         if (name != "" && error == "") {
@@ -1422,7 +1535,8 @@
                     } else if (tag == "package-verifier") {
                         String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);
                         if (name != "" && error == "") {
-                            String8 publicKey = AaptXml::getAttribute(tree, PUBLIC_KEY_ATTR, &error);
+                            String8 publicKey = AaptXml::getAttribute(tree, PUBLIC_KEY_ATTR,
+                                                                      &error);
                             if (publicKey != "" && error == "") {
                                 printf("package-verifier: name='%s' publicKey='%s'\n",
                                         ResTable::normalizeForOutput(name.string()).string(),
@@ -1485,12 +1599,18 @@
                             if (error == "") {
                                 if (orien == 0 || orien == 6 || orien == 8) {
                                     // Requests landscape, sensorLandscape, or reverseLandscape.
-                                    addImpliedFeature(&impliedFeatures, "android.hardware.screen.landscape",
-                                            "one or more activities have specified a landscape orientation");
+                                    addImpliedFeature(&impliedFeatures,
+                                                      "android.hardware.screen.landscape",
+                                                      "one or more activities have specified a "
+                                                      "landscape orientation",
+                                                      false);
                                 } else if (orien == 1 || orien == 7 || orien == 9) {
                                     // Requests portrait, sensorPortrait, or reversePortrait.
-                                    addImpliedFeature(&impliedFeatures, "android.hardware.screen.portrait",
-                                            "one or more activities have specified a portrait orientation");
+                                    addImpliedFeature(&impliedFeatures,
+                                                      "android.hardware.screen.portrait",
+                                                      "one or more activities have specified a "
+                                                      "portrait orientation",
+                                                      false);
                                 }
                             }
                         } else if (tag == "uses-library") {
@@ -1524,8 +1644,10 @@
                                     hasBindDeviceAdminPermission = true;
                                 }
                             } else {
-                                fprintf(stderr, "ERROR getting 'android:permission' attribute for"
-                                        " receiver '%s': %s\n", receiverName.string(), error.string());
+                                fprintf(stderr,
+                                        "ERROR getting 'android:permission' attribute for"
+                                        " receiver '%s': %s\n",
+                                        receiverName.string(), error.string());
                             }
                         } else if (tag == "service") {
                             withinService = true;
@@ -1542,20 +1664,24 @@
                             if (error == "") {
                                 if (permission == "android.permission.BIND_INPUT_METHOD") {
                                     hasBindInputMethodPermission = true;
-                                } else if (permission == "android.permission.BIND_ACCESSIBILITY_SERVICE") {
+                                } else if (permission ==
+                                        "android.permission.BIND_ACCESSIBILITY_SERVICE") {
                                     hasBindAccessibilityServicePermission = true;
-                                } else if (permission == "android.permission.BIND_PRINT_SERVICE") {
+                                } else if (permission ==
+                                        "android.permission.BIND_PRINT_SERVICE") {
                                     hasBindPrintServicePermission = true;
-                                } else if (permission == "android.permission.BIND_NFC_SERVICE") {
+                                } else if (permission ==
+                                        "android.permission.BIND_NFC_SERVICE") {
                                     hasBindNfcServicePermission = true;
-                                } else if (permission == "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE") {
+                                } else if (permission ==
+                                        "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE") {
                                     hasBindNotificationListenerServicePermission = true;
                                 } else if (permission == "android.permission.BIND_DREAM_SERVICE") {
                                     hasBindDreamServicePermission = true;
                                 }
                             } else {
-                                fprintf(stderr, "ERROR getting 'android:permission' attribute for"
-                                        " service '%s': %s\n", serviceName.string(), error.string());
+                                fprintf(stderr, "ERROR getting 'android:permission' attribute for "
+                                        "service '%s': %s\n", serviceName.string(), error.string());
                             }
                         } else if (tag == "provider") {
                             withinProvider = true;
@@ -1563,7 +1689,8 @@
                             bool exported = AaptXml::getResolvedIntegerAttribute(res, tree,
                                     EXPORTED_ATTR, &error);
                             if (error != "") {
-                                fprintf(stderr, "ERROR getting 'android:exported' attribute for provider:"
+                                fprintf(stderr,
+                                        "ERROR getting 'android:exported' attribute for provider:"
                                         " %s\n", error.string());
                                 goto bail;
                             }
@@ -1571,16 +1698,17 @@
                             bool grantUriPermissions = AaptXml::getResolvedIntegerAttribute(
                                     res, tree, GRANT_URI_PERMISSIONS_ATTR, &error);
                             if (error != "") {
-                                fprintf(stderr, "ERROR getting 'android:grantUriPermissions' attribute for provider:"
-                                        " %s\n", error.string());
+                                fprintf(stderr,
+                                        "ERROR getting 'android:grantUriPermissions' attribute for "
+                                        "provider: %s\n", error.string());
                                 goto bail;
                             }
 
                             String8 permission = AaptXml::getResolvedAttribute(res, tree,
                                     PERMISSION_ATTR, &error);
                             if (error != "") {
-                                fprintf(stderr, "ERROR getting 'android:permission' attribute for provider:"
-                                        " %s\n", error.string());
+                                fprintf(stderr, "ERROR getting 'android:permission' attribute for "
+                                        "provider: %s\n", error.string());
                                 goto bail;
                             }
 
@@ -1661,8 +1789,9 @@
                     } else if (withinService && tag == "meta-data") {
                         String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);
                         if (error != "") {
-                            fprintf(stderr, "ERROR getting 'android:name' attribute for"
-                                    " meta-data tag in service '%s': %s\n", serviceName.string(), error.string());
+                            fprintf(stderr, "ERROR getting 'android:name' attribute for "
+                                    "meta-data tag in service '%s': %s\n", serviceName.string(),
+                                    error.string());
                             goto bail;
                         }
 
@@ -1676,8 +1805,9 @@
                             String8 xmlPath = AaptXml::getResolvedAttribute(res, tree,
                                     RESOURCE_ATTR, &error);
                             if (error != "") {
-                                fprintf(stderr, "ERROR getting 'android:resource' attribute for"
-                                        " meta-data tag in service '%s': %s\n", serviceName.string(), error.string());
+                                fprintf(stderr, "ERROR getting 'android:resource' attribute for "
+                                        "meta-data tag in service '%s': %s\n",
+                                        serviceName.string(), error.string());
                                 goto bail;
                             }
 
@@ -1731,15 +1861,19 @@
                                 actImeService = true;
                             } else if (action == "android.service.wallpaper.WallpaperService") {
                                 actWallpaperService = true;
-                            } else if (action == "android.accessibilityservice.AccessibilityService") {
+                            } else if (action ==
+                                    "android.accessibilityservice.AccessibilityService") {
                                 actAccessibilityService = true;
-                            } else if (action == "android.printservice.PrintService") {
+                            } else if (action =="android.printservice.PrintService") {
                                 actPrintService = true;
-                            } else if (action == "android.nfc.cardemulation.action.HOST_APDU_SERVICE") {
+                            } else if (action ==
+                                    "android.nfc.cardemulation.action.HOST_APDU_SERVICE") {
                                 actHostApduService = true;
-                            } else if (action == "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE") {
+                            } else if (action ==
+                                    "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE") {
                                 actOffHostApduService = true;
-                            } else if (action == "android.service.notification.NotificationListenerService") {
+                            } else if (action ==
+                                    "android.service.notification.NotificationListenerService") {
                                 actNotificationListenerService = true;
                             } else if (action == "android.service.dreams.DreamService") {
                                 actDreamService = true;
@@ -1814,12 +1948,12 @@
             }
 
             addImpliedFeature(&impliedFeatures, "android.hardware.touchscreen",
-                    "default feature for all apps");
+                    "default feature for all apps", false);
 
             const size_t numFeatureGroups = featureGroups.size();
             if (numFeatureGroups == 0) {
                 // If no <feature-group> tags were defined, apply auto-implied features.
-                printFeatureGroup(commonFeatures, &impliedFeatures);
+                printDefaultFeatureGroup(commonFeatures, impliedFeatures);
 
             } else {
                 // <feature-group> tags are defined, so we ignore implied features and
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index 6411286..c424cc5 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -220,7 +220,9 @@
         "       Prevents symbols from being generated for strings that do not have a default\n"
         "       localization\n"
         "   --no-version-vectors\n"
-        "       Do not automatically generate versioned copies of vector XML resources.\n",
+        "       Do not automatically generate versioned copies of vector XML resources.\n"
+        "   --private-symbols\n"
+        "       Java package name to use when generating R.java for private resources.\n",
         gDefaultIgnoreAssets);
 }
 
@@ -689,6 +691,16 @@
                     bundle.setPseudolocalize(PSEUDO_ACCENTED | PSEUDO_BIDI);
                 } else if (strcmp(cp, "-no-version-vectors") == 0) {
                     bundle.setNoVersionVectors(true);
+                } else if (strcmp(cp, "-private-symbols") == 0) {
+                    argc--;
+                    argv++;
+                    if (!argc) {
+                        fprintf(stderr, "ERROR: No argument supplied for "
+                                "'--private-symbols' option\n");
+                        wantUsage = true;
+                        goto bail;
+                    }
+                    bundle.setPrivateSymbolsPackage(String8(argv[0]));
                 } else {
                     fprintf(stderr, "ERROR: Unknown option '-%s'\n", cp);
                     wantUsage = true;
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index fb0fe38..576f076 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -1161,6 +1161,12 @@
         printf("Creating resources for package %s\n", assets->getPackage().string());
     }
 
+    // Set the private symbols package if it was declared.
+    // This can also be declared in XML as <private-symbols name="package" />
+    if (bundle->getPrivateSymbolsPackage().size() != 0) {
+        assets->setSymbolsPrivatePackage(bundle->getPrivateSymbolsPackage());
+    }
+
     ResourceTable::PackageType packageType = ResourceTable::App;
     if (bundle->getBuildSharedLibrary()) {
         packageType = ResourceTable::SharedLibrary;
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 0e470d9..e87c7d40 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -1141,7 +1141,15 @@
                 }
                 pkg = String16(block.getAttributeStringValue(pkgIdx, &len));
                 if (!localHasErrors) {
-                    assets->setSymbolsPrivatePackage(String8(pkg));
+                    SourcePos(in->getPrintableSource(), block.getLineNumber()).warning(
+                            "<private-symbols> is deprecated. Use the command line flag "
+                            "--private-symbols instead.\n");
+                    if (assets->havePrivateSymbols()) {
+                        SourcePos(in->getPrintableSource(), block.getLineNumber()).warning(
+                                "private symbol package already specified. Ignoring...\n");
+                    } else {
+                        assets->setSymbolsPrivatePackage(String8(pkg));
+                    }
                 }
 
                 while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk
index d8e0aac..0f83980 100644
--- a/tools/aapt2/Android.mk
+++ b/tools/aapt2/Android.mk
@@ -31,6 +31,8 @@
 	flatten/Archive.cpp \
 	flatten/TableFlattener.cpp \
 	flatten/XmlFlattener.cpp \
+	io/FileSystem.cpp \
+	io/ZipArchive.cpp \
 	link/AutoVersioner.cpp \
 	link/ManifestFixer.cpp \
 	link/PrivateAttributeMover.cpp \
diff --git a/tools/aapt2/NameMangler.h b/tools/aapt2/NameMangler.h
index 6d752bb..054b9ee 100644
--- a/tools/aapt2/NameMangler.h
+++ b/tools/aapt2/NameMangler.h
@@ -60,7 +60,7 @@
         };
     }
 
-    bool shouldMangle(const std::u16string& package) {
+    bool shouldMangle(const std::u16string& package) const {
         if (package.empty() || mPolicy.targetPackageName == package) {
             return false;
         }
diff --git a/tools/aapt2/Resource.cpp b/tools/aapt2/Resource.cpp
index 34dc1d5..9328b69 100644
--- a/tools/aapt2/Resource.cpp
+++ b/tools/aapt2/Resource.cpp
@@ -85,4 +85,12 @@
     return &iter->second;
 }
 
+bool operator<(const ResourceKey& a, const ResourceKey& b) {
+    return std::tie(a.name, a.config) < std::tie(b.name, b.config);
+}
+
+bool operator<(const ResourceKeyRef& a, const ResourceKeyRef& b) {
+    return std::tie(a.name, a.config) < std::tie(b.name, b.config);
+}
+
 } // namespace aapt
diff --git a/tools/aapt2/Resource.h b/tools/aapt2/Resource.h
index a7afbb5..c71e249 100644
--- a/tools/aapt2/Resource.h
+++ b/tools/aapt2/Resource.h
@@ -165,6 +165,36 @@
     std::vector<SourcedResourceName> exportedSymbols;
 };
 
+/**
+ * Useful struct used as a key to represent a unique resource in associative containers.
+ */
+struct ResourceKey {
+    ResourceName name;
+    ConfigDescription config;
+};
+
+bool operator<(const ResourceKey& a, const ResourceKey& b);
+
+/**
+ * Useful struct used as a key to represent a unique resource in associative containers.
+ * Holds a reference to the name, so that name better live longer than this key!
+ */
+struct ResourceKeyRef {
+    ResourceNameRef name;
+    ConfigDescription config;
+
+    ResourceKeyRef() = default;
+    ResourceKeyRef(const ResourceNameRef& n, const ConfigDescription& c) : name(n), config(c) {
+    }
+
+    /**
+     * Prevent taking a reference to a temporary. This is bad.
+     */
+    ResourceKeyRef(ResourceName&& n, const ConfigDescription& c) = delete;
+};
+
+bool operator<(const ResourceKeyRef& a, const ResourceKeyRef& b);
+
 //
 // ResourceId implementation.
 //
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index c2ddb5c..d4c536f 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -173,7 +173,7 @@
     ResourceName name;
     Source source;
     ResourceId id;
-    SymbolState symbolState = SymbolState::kUndefined;
+    Maybe<SymbolState> symbolState;
     std::u16string comment;
     std::unique_ptr<Value> value;
     std::list<ParsedResource> childResources;
@@ -182,9 +182,9 @@
 // Recursively adds resources to the ResourceTable.
 static bool addResourcesToTable(ResourceTable* table, const ConfigDescription& config,
                                 IDiagnostics* diag, ParsedResource* res) {
-    if (res->symbolState != SymbolState::kUndefined) {
+    if (res->symbolState) {
         Symbol symbol;
-        symbol.state = res->symbolState;
+        symbol.state = res->symbolState.value();
         symbol.source = res->source;
         symbol.comment = res->comment;
         if (!table->setSymbolState(res->name, res->id, symbol, diag)) {
@@ -325,6 +325,8 @@
             result = parseSymbol(parser, &parsedResource);
         } else if (elementName == u"public-group") {
             result = parsePublicGroup(parser, &parsedResource);
+        } else if (elementName == u"add-resource") {
+            result = parseAddResource(parser, &parsedResource);
         } else {
             // Try parsing the elementName (or type) as a resource. These shall only be
             // resources like 'layout' or 'xml' and they can only be references.
@@ -643,7 +645,7 @@
     return !error;
 }
 
-bool ResourceParser::parseSymbol(xml::XmlPullParser* parser, ParsedResource* outResource) {
+bool ResourceParser::parseSymbolImpl(xml::XmlPullParser* parser, ParsedResource* outResource) {
     const Source source = mSource.withLine(parser->getLineNumber());
 
     Maybe<StringPiece16> maybeType = xml::findNonEmptyAttribute(parser, u"type");
@@ -661,10 +663,25 @@
     }
 
     outResource->name.type = *parsedType;
-    outResource->symbolState = SymbolState::kPrivate;
     return true;
 }
 
+bool ResourceParser::parseSymbol(xml::XmlPullParser* parser, ParsedResource* outResource) {
+    if (parseSymbolImpl(parser, outResource)) {
+        outResource->symbolState = SymbolState::kPrivate;
+        return true;
+    }
+    return false;
+}
+
+bool ResourceParser::parseAddResource(xml::XmlPullParser* parser, ParsedResource* outResource) {
+    if (parseSymbolImpl(parser, outResource)) {
+        outResource->symbolState = SymbolState::kUndefined;
+        return true;
+    }
+    return false;
+}
+
 static uint32_t parseFormatType(const StringPiece16& piece) {
     if (piece == u"reference")      return android::ResTable_map::TYPE_REFERENCE;
     else if (piece == u"string")    return android::ResTable_map::TYPE_STRING;
@@ -870,7 +887,7 @@
     }
 
     return Attribute::Symbol{
-            Reference(ResourceName({}, ResourceType::kId, maybeName.value().toString())),
+            Reference(ResourceNameRef({}, ResourceType::kId, maybeName.value())),
             val.data };
 }
 
diff --git a/tools/aapt2/ResourceParser.h b/tools/aapt2/ResourceParser.h
index 1150758..04db577 100644
--- a/tools/aapt2/ResourceParser.h
+++ b/tools/aapt2/ResourceParser.h
@@ -83,7 +83,9 @@
     bool parsePrimitive(xml::XmlPullParser* parser, ParsedResource* outResource);
     bool parsePublic(xml::XmlPullParser* parser, ParsedResource* outResource);
     bool parsePublicGroup(xml::XmlPullParser* parser, ParsedResource* outResource);
+    bool parseSymbolImpl(xml::XmlPullParser* parser, ParsedResource* outResource);
     bool parseSymbol(xml::XmlPullParser* parser, ParsedResource* outResource);
+    bool parseAddResource(xml::XmlPullParser* parser, ParsedResource* outResource);
     bool parseAttr(xml::XmlPullParser* parser, ParsedResource* outResource);
     bool parseAttrImpl(xml::XmlPullParser* parser, ParsedResource* outResource, bool weak);
     Maybe<Attribute::Symbol> parseEnumOrFlagItem(xml::XmlPullParser* parser,
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index 6e0812b..84f67c6 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -563,4 +563,16 @@
     ASSERT_FALSE(testParse(input));
 }
 
+TEST_F(ResourceParserTest, AddResourcesElementShouldAddEntryWithUndefinedSymbol) {
+    std::string input = R"EOF(<add-resource name="bar" type="string" />)EOF";
+    ASSERT_TRUE(testParse(input));
+
+    Maybe<ResourceTable::SearchResult> result = mTable.findResource(
+            test::parseNameOrDie(u"@string/bar"));
+    AAPT_ASSERT_TRUE(result);
+    const ResourceEntry* entry = result.value().entry;
+    ASSERT_NE(nullptr, entry);
+    EXPECT_EQ(SymbolState::kUndefined, entry->symbolStatus.state);
+}
+
 } // namespace aapt
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index 73d8585..8a3d047 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -101,7 +101,7 @@
     if (iter != last && (*iter)->type == type) {
         return iter->get();
     }
-    return types.emplace(iter, new ResourceTableType{ type })->get();
+    return types.emplace(iter, new ResourceTableType(type))->get();
 }
 
 ResourceEntry* ResourceTableType::findEntry(const StringPiece16& name) {
@@ -121,7 +121,7 @@
     if (iter != last && name == (*iter)->name) {
         return iter->get();
     }
-    return entries.emplace(iter, new ResourceEntry{ name })->get();
+    return entries.emplace(iter, new ResourceEntry(name))->get();
 }
 
 /**
@@ -342,11 +342,6 @@
                                        IDiagnostics* diag) {
     assert(diag && "diagnostics can't be nullptr");
 
-    if (symbol.state == SymbolState::kUndefined) {
-        // Nothing to do.
-        return true;
-    }
-
     auto badCharIter = util::findNonAlphaNumericAndNotInSet(name.entry, validChars);
     if (badCharIter != name.entry.end()) {
         diag->error(DiagMessage(symbol.source)
@@ -400,23 +395,30 @@
         return false;
     }
 
-    // Only mark the type state as public, it doesn't care about being private.
-    if (symbol.state == SymbolState::kPublic) {
-        type->symbolStatus.state = SymbolState::kPublic;
-    }
-
-    // Downgrading to a private symbol from a public one is not allowed.
-    if (entry->symbolStatus.state != SymbolState::kPublic) {
-        if (entry->symbolStatus.state != symbol.state) {
-            entry->symbolStatus = std::move(symbol);
-        }
-    }
-
     if (resId.isValid()) {
         package->id = resId.packageId();
         type->id = resId.typeId();
         entry->id = resId.entryId();
     }
+
+    // Only mark the type state as public, it doesn't care about being private.
+    if (symbol.state == SymbolState::kPublic) {
+        type->symbolStatus.state = SymbolState::kPublic;
+    }
+
+    if (symbol.state == SymbolState::kUndefined &&
+            entry->symbolStatus.state != SymbolState::kUndefined) {
+        // We can't undefine a symbol (remove its visibility). Ignore.
+        return true;
+    }
+
+    if (symbol.state == SymbolState::kPrivate &&
+            entry->symbolStatus.state == SymbolState::kPublic) {
+        // We can't downgrade public to private. Ignore.
+        return true;
+    }
+
+    entry->symbolStatus = std::move(symbol);
     return true;
 }
 
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index ffe6595..36c3e70 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -14,8 +14,10 @@
  * limitations under the License.
  */
 
+#include "NameMangler.h"
 #include "ResourceUtils.h"
 #include "flatten/ResourceTypeExtensions.h"
+#include "util/Files.h"
 #include "util/Util.h"
 
 #include <androidfw/ResourceTypes.h>
@@ -554,5 +556,22 @@
     return {};
 }
 
+std::string buildResourceFileName(const ResourceFile& resFile, const NameMangler* mangler) {
+    std::stringstream out;
+    out << "res/" << resFile.name.type;
+    if (resFile.config != ConfigDescription{}) {
+        out << "-" << resFile.config;
+    }
+    out << "/";
+
+    if (mangler && mangler->shouldMangle(resFile.name.package)) {
+        out << NameMangler::mangleEntry(resFile.name.package, resFile.name.entry);
+    } else {
+        out << resFile.name.entry;
+    }
+    out << file::getExtension(resFile.source.path);
+    return out.str();
+}
+
 } // namespace ResourceUtils
 } // namespace aapt
diff --git a/tools/aapt2/ResourceUtils.h b/tools/aapt2/ResourceUtils.h
index f93a4c7..64ca971 100644
--- a/tools/aapt2/ResourceUtils.h
+++ b/tools/aapt2/ResourceUtils.h
@@ -17,6 +17,7 @@
 #ifndef AAPT_RESOURCEUTILS_H
 #define AAPT_RESOURCEUTILS_H
 
+#include "NameMangler.h"
 #include "Resource.h"
 #include "ResourceValues.h"
 #include "util/StringPiece.h"
@@ -154,6 +155,16 @@
 
 uint32_t androidTypeToAttributeTypeMask(uint16_t type);
 
+/**
+ * Returns a string path suitable for use within an APK. The path will look like:
+ *
+ * res/type[-config]/<name>.<ext>
+ *
+ * Then name may be mangled if a NameMangler is supplied (can be nullptr) and the package
+ * requires mangling.
+ */
+std::string buildResourceFileName(const ResourceFile& resFile, const NameMangler* mangler);
+
 } // namespace ResourceUtils
 } // namespace aapt
 
diff --git a/tools/aapt2/flatten/TableFlattener.cpp b/tools/aapt2/flatten/TableFlattener.cpp
index f42e6b7..a2f53e1 100644
--- a/tools/aapt2/flatten/TableFlattener.cpp
+++ b/tools/aapt2/flatten/TableFlattener.cpp
@@ -23,7 +23,7 @@
 #include "flatten/TableFlattener.h"
 #include "util/BigBuffer.h"
 
-#include <base/macros.h>
+#include <android-base/macros.h>
 #include <type_traits>
 #include <numeric>
 
@@ -583,8 +583,8 @@
                     publicEntry->state = Public_entry::kPublic;
                     break;
 
-                default:
-                    assert(false && "should not serialize any other state");
+                case SymbolState::kUndefined:
+                    publicEntry->state = Public_entry::kUndefined;
                     break;
                 }
 
diff --git a/tools/aapt2/io/File.h b/tools/aapt2/io/File.h
index 9fca398..b4d4971 100644
--- a/tools/aapt2/io/File.h
+++ b/tools/aapt2/io/File.h
@@ -52,6 +52,14 @@
     virtual const Source& getSource() const = 0;
 };
 
+class IFileCollectionIterator {
+public:
+    virtual ~IFileCollectionIterator() = default;
+
+    virtual bool hasNext() = 0;
+    virtual IFile* next() = 0;
+};
+
 /**
  * Interface for a collection of files, all of which share a common source. That source may
  * simply be the filesystem, or a ZIP archive.
@@ -60,10 +68,8 @@
 public:
     virtual ~IFileCollection() = default;
 
-    using const_iterator = std::vector<std::unique_ptr<IFile>>::const_iterator;
-
-    virtual const_iterator begin() const = 0;
-    virtual const_iterator end() const = 0;
+    virtual IFile* findFile(const StringPiece& path) = 0;
+    virtual std::unique_ptr<IFileCollectionIterator> iterator() = 0;
 };
 
 } // namespace io
diff --git a/tools/aapt2/io/FileSystem.cpp b/tools/aapt2/io/FileSystem.cpp
new file mode 100644
index 0000000..76f87ae
--- /dev/null
+++ b/tools/aapt2/io/FileSystem.cpp
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+#include "Source.h"
+#include "io/FileSystem.h"
+#include "util/Files.h"
+#include "util/Maybe.h"
+#include "util/StringPiece.h"
+#include "util/Util.h"
+
+#include <utils/FileMap.h>
+
+namespace aapt {
+namespace io {
+
+RegularFile::RegularFile(const Source& source) : mSource(source) {
+}
+
+std::unique_ptr<IData> RegularFile::openAsData() {
+    android::FileMap map;
+    if (Maybe<android::FileMap> map = file::mmapPath(mSource.path, nullptr)) {
+        return util::make_unique<MmappedData>(std::move(map.value()));
+    }
+    return {};
+}
+
+const Source& RegularFile::getSource() const {
+    return mSource;
+}
+
+FileCollectionIterator::FileCollectionIterator(FileCollection* collection) :
+        mCurrent(collection->mFiles.begin()), mEnd(collection->mFiles.end()) {
+}
+
+bool FileCollectionIterator::hasNext() {
+    return mCurrent != mEnd;
+}
+
+IFile* FileCollectionIterator::next() {
+    IFile* result = mCurrent->second.get();
+    ++mCurrent;
+    return result;
+}
+
+IFile* FileCollection::insertFile(const StringPiece& path) {
+    return (mFiles[path.toString()] = util::make_unique<RegularFile>(Source(path))).get();
+}
+
+IFile* FileCollection::findFile(const StringPiece& path) {
+    auto iter = mFiles.find(path.toString());
+    if (iter != mFiles.end()) {
+        return iter->second.get();
+    }
+    return nullptr;
+}
+
+std::unique_ptr<IFileCollectionIterator> FileCollection::iterator() {
+    return util::make_unique<FileCollectionIterator>(this);
+}
+
+} // namespace io
+} // namespace aapt
diff --git a/tools/aapt2/io/FileSystem.h b/tools/aapt2/io/FileSystem.h
index 5dbefcc..f0559c0 100644
--- a/tools/aapt2/io/FileSystem.h
+++ b/tools/aapt2/io/FileSystem.h
@@ -18,7 +18,8 @@
 #define AAPT_IO_FILESYSTEM_H
 
 #include "io/File.h"
-#include "util/Files.h"
+
+#include <map>
 
 namespace aapt {
 namespace io {
@@ -28,25 +29,28 @@
  */
 class RegularFile : public IFile {
 public:
-    RegularFile(const Source& source) : mSource(source) {
-    }
+    RegularFile(const Source& source);
 
-    std::unique_ptr<IData> openAsData() override {
-        android::FileMap map;
-        if (Maybe<android::FileMap> map = file::mmapPath(mSource.path, nullptr)) {
-            return util::make_unique<MmappedData>(std::move(map.value()));
-        }
-        return {};
-    }
-
-    const Source& getSource() const override {
-        return mSource;
-    }
+    std::unique_ptr<IData> openAsData() override;
+    const Source& getSource() const override;
 
 private:
     Source mSource;
 };
 
+class FileCollection;
+
+class FileCollectionIterator : public IFileCollectionIterator {
+public:
+    FileCollectionIterator(FileCollection* collection);
+
+    bool hasNext() override;
+    io::IFile* next() override;
+
+private:
+    std::map<std::string, std::unique_ptr<IFile>>::const_iterator mCurrent, mEnd;
+};
+
 /**
  * An IFileCollection representing the file system.
  */
@@ -55,21 +59,13 @@
     /**
      * Adds a file located at path. Returns the IFile representation of that file.
      */
-    IFile* insertFile(const StringPiece& path) {
-        mFiles.push_back(util::make_unique<RegularFile>(Source(path)));
-        return mFiles.back().get();
-    }
-
-    const_iterator begin() const override {
-        return mFiles.begin();
-    }
-
-    const_iterator end() const override {
-        return mFiles.end();
-    }
+    IFile* insertFile(const StringPiece& path);
+    IFile* findFile(const StringPiece& path) override;
+    std::unique_ptr<IFileCollectionIterator> iterator() override;
 
 private:
-    std::vector<std::unique_ptr<IFile>> mFiles;
+    friend class FileCollectionIterator;
+    std::map<std::string, std::unique_ptr<IFile>> mFiles;
 };
 
 } // namespace io
diff --git a/tools/aapt2/io/ZipArchive.cpp b/tools/aapt2/io/ZipArchive.cpp
new file mode 100644
index 0000000..bf0f4aa
--- /dev/null
+++ b/tools/aapt2/io/ZipArchive.cpp
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+
+#include "Source.h"
+#include "io/ZipArchive.h"
+#include "util/Util.h"
+
+#include <utils/FileMap.h>
+#include <ziparchive/zip_archive.h>
+
+namespace aapt {
+namespace io {
+
+ZipFile::ZipFile(ZipArchiveHandle handle, const ZipEntry& entry, const Source& source) :
+        mZipHandle(handle), mZipEntry(entry), mSource(source) {
+}
+
+std::unique_ptr<IData> ZipFile::openAsData() {
+    if (mZipEntry.method == kCompressStored) {
+        int fd = GetFileDescriptor(mZipHandle);
+
+        android::FileMap fileMap;
+        bool result = fileMap.create(nullptr, fd, mZipEntry.offset,
+                                     mZipEntry.uncompressed_length, true);
+        if (!result) {
+            return {};
+        }
+        return util::make_unique<MmappedData>(std::move(fileMap));
+
+    } else {
+        std::unique_ptr<uint8_t[]> data = std::unique_ptr<uint8_t[]>(
+                new uint8_t[mZipEntry.uncompressed_length]);
+        int32_t result = ExtractToMemory(mZipHandle, &mZipEntry, data.get(),
+                                         static_cast<uint32_t>(mZipEntry.uncompressed_length));
+        if (result != 0) {
+            return {};
+        }
+        return util::make_unique<MallocData>(std::move(data), mZipEntry.uncompressed_length);
+    }
+}
+
+const Source& ZipFile::getSource() const {
+    return mSource;
+}
+
+ZipFileCollectionIterator::ZipFileCollectionIterator(ZipFileCollection* collection) :
+        mCurrent(collection->mFiles.begin()), mEnd(collection->mFiles.end()) {
+}
+
+bool ZipFileCollectionIterator::hasNext() {
+    return mCurrent != mEnd;
+}
+
+IFile* ZipFileCollectionIterator::next() {
+    IFile* result = mCurrent->second.get();
+    ++mCurrent;
+    return result;
+}
+
+ZipFileCollection::ZipFileCollection() : mHandle(nullptr) {
+}
+
+std::unique_ptr<ZipFileCollection> ZipFileCollection::create(const StringPiece& path,
+                                                             std::string* outError) {
+    std::unique_ptr<ZipFileCollection> collection = std::unique_ptr<ZipFileCollection>(
+            new ZipFileCollection());
+
+    int32_t result = OpenArchive(path.data(), &collection->mHandle);
+    if (result != 0) {
+        if (outError) *outError = ErrorCodeString(result);
+        return {};
+    }
+
+    ZipString suffix(".flat");
+    void* cookie = nullptr;
+    result = StartIteration(collection->mHandle, &cookie, nullptr, &suffix);
+    if (result != 0) {
+        if (outError) *outError = ErrorCodeString(result);
+        return {};
+    }
+
+    using IterationEnder = std::unique_ptr<void, decltype(EndIteration)*>;
+    IterationEnder iterationEnder(cookie, EndIteration);
+
+    ZipString zipEntryName;
+    ZipEntry zipData;
+    while ((result = Next(cookie, &zipData, &zipEntryName)) == 0) {
+        std::string zipEntryPath = std::string(reinterpret_cast<const char*>(zipEntryName.name),
+                                               zipEntryName.name_length);
+        std::string nestedPath = path.toString() + "@" + zipEntryPath;
+        collection->mFiles[zipEntryPath] = util::make_unique<ZipFile>(collection->mHandle,
+                                                                      zipData,
+                                                                      Source(nestedPath));
+    }
+
+    if (result != -1) {
+        if (outError) *outError = ErrorCodeString(result);
+        return {};
+    }
+    return collection;
+}
+
+IFile* ZipFileCollection::findFile(const StringPiece& path) {
+    auto iter = mFiles.find(path.toString());
+    if (iter != mFiles.end()) {
+        return iter->second.get();
+    }
+    return nullptr;
+}
+
+std::unique_ptr<IFileCollectionIterator> ZipFileCollection::iterator() {
+    return util::make_unique<ZipFileCollectionIterator>(this);
+}
+
+ZipFileCollection::~ZipFileCollection() {
+    if (mHandle) {
+        CloseArchive(mHandle);
+    }
+}
+
+} // namespace io
+} // namespace aapt
diff --git a/tools/aapt2/io/ZipArchive.h b/tools/aapt2/io/ZipArchive.h
index 98afc49..5ad119d 100644
--- a/tools/aapt2/io/ZipArchive.h
+++ b/tools/aapt2/io/ZipArchive.h
@@ -20,7 +20,7 @@
 #include "io/File.h"
 #include "util/StringPiece.h"
 
-#include <utils/FileMap.h>
+#include <map>
 #include <ziparchive/zip_archive.h>
 
 namespace aapt {
@@ -32,37 +32,10 @@
  */
 class ZipFile : public IFile {
 public:
-    ZipFile(ZipArchiveHandle handle, const ZipEntry& entry, const Source& source) :
-            mZipHandle(handle), mZipEntry(entry), mSource(source) {
-    }
+    ZipFile(ZipArchiveHandle handle, const ZipEntry& entry, const Source& source);
 
-    std::unique_ptr<IData> openAsData() override {
-        if (mZipEntry.method == kCompressStored) {
-            int fd = GetFileDescriptor(mZipHandle);
-
-            android::FileMap fileMap;
-            bool result = fileMap.create(nullptr, fd, mZipEntry.offset,
-                                         mZipEntry.uncompressed_length, true);
-            if (!result) {
-                return {};
-            }
-            return util::make_unique<MmappedData>(std::move(fileMap));
-
-        } else {
-            std::unique_ptr<uint8_t[]> data = std::unique_ptr<uint8_t[]>(
-                    new uint8_t[mZipEntry.uncompressed_length]);
-            int32_t result = ExtractToMemory(mZipHandle, &mZipEntry, data.get(),
-                                             static_cast<uint32_t>(mZipEntry.uncompressed_length));
-            if (result != 0) {
-                return {};
-            }
-            return util::make_unique<MallocData>(std::move(data), mZipEntry.uncompressed_length);
-        }
-    }
-
-    const Source& getSource() const override {
-        return mSource;
-    }
+    std::unique_ptr<IData> openAsData() override;
+    const Source& getSource() const override;
 
 private:
     ZipArchiveHandle mZipHandle;
@@ -70,71 +43,38 @@
     Source mSource;
 };
 
+class ZipFileCollection;
+
+class ZipFileCollectionIterator : public IFileCollectionIterator {
+public:
+    ZipFileCollectionIterator(ZipFileCollection* collection);
+
+    bool hasNext() override;
+    io::IFile* next() override;
+
+private:
+    std::map<std::string, std::unique_ptr<IFile>>::const_iterator mCurrent, mEnd;
+};
+
 /**
  * An IFileCollection that represents a ZIP archive and the entries within it.
  */
 class ZipFileCollection : public IFileCollection {
 public:
     static std::unique_ptr<ZipFileCollection> create(const StringPiece& path,
-                                                     std::string* outError) {
-        std::unique_ptr<ZipFileCollection> collection = std::unique_ptr<ZipFileCollection>(
-                new ZipFileCollection());
+                                                     std::string* outError);
 
-        int32_t result = OpenArchive(path.data(), &collection->mHandle);
-        if (result != 0) {
-            if (outError) *outError = ErrorCodeString(result);
-            return {};
-        }
+    io::IFile* findFile(const StringPiece& path) override;
+    std::unique_ptr<IFileCollectionIterator> iterator() override;
 
-        ZipString suffix(".flat");
-        void* cookie = nullptr;
-        result = StartIteration(collection->mHandle, &cookie, nullptr, &suffix);
-        if (result != 0) {
-            if (outError) *outError = ErrorCodeString(result);
-            return {};
-        }
-
-        using IterationEnder = std::unique_ptr<void, decltype(EndIteration)*>;
-        IterationEnder iterationEnder(cookie, EndIteration);
-
-        ZipString zipEntryName;
-        ZipEntry zipData;
-        while ((result = Next(cookie, &zipData, &zipEntryName)) == 0) {
-            std::string nestedPath = path.toString();
-            nestedPath += "@" + std::string(reinterpret_cast<const char*>(zipEntryName.name),
-                                            zipEntryName.name_length);
-            collection->mFiles.push_back(util::make_unique<ZipFile>(collection->mHandle,
-                                                                    zipData,
-                                                                    Source(nestedPath)));
-        }
-
-        if (result != -1) {
-            if (outError) *outError = ErrorCodeString(result);
-            return {};
-        }
-        return collection;
-    }
-
-    const_iterator begin() const override {
-        return mFiles.begin();
-    }
-
-    const_iterator end() const override {
-        return mFiles.end();
-    }
-
-    ~ZipFileCollection() override {
-        if (mHandle) {
-            CloseArchive(mHandle);
-        }
-    }
+    ~ZipFileCollection() override;
 
 private:
-    ZipFileCollection() : mHandle(nullptr) {
-    }
+    friend class ZipFileCollectionIterator;
+    ZipFileCollection();
 
     ZipArchiveHandle mHandle;
-    std::vector<std::unique_ptr<IFile>> mFiles;
+    std::map<std::string, std::unique_ptr<IFile>> mFiles;
 };
 
 } // namespace io
diff --git a/tools/aapt2/link/Link.cpp b/tools/aapt2/link/Link.cpp
index 33d9272..652e52f 100644
--- a/tools/aapt2/link/Link.cpp
+++ b/tools/aapt2/link/Link.cpp
@@ -57,6 +57,7 @@
     bool staticLib = false;
     bool verbose = false;
     bool outputToDirectory = false;
+    bool autoAddOverlay = false;
     Maybe<std::u16string> privateSymbols;
     Maybe<std::u16string> minSdkVersionDefault;
     Maybe<std::u16string> targetSdkVersionDefault;
@@ -104,23 +105,6 @@
         mCollections.push_back(std::move(fileCollection));
     }
 
-    std::string buildResourceFileName(const ResourceFile& resFile) {
-        std::stringstream out;
-        out << "res/" << resFile.name.type;
-        if (resFile.config != ConfigDescription{}) {
-            out << "-" << resFile.config;
-        }
-        out << "/";
-
-        if (mContext.getNameMangler()->shouldMangle(resFile.name.package)) {
-            out << NameMangler::mangleEntry(resFile.name.package, resFile.name.entry);
-        } else {
-            out << resFile.name.entry;
-        }
-        out << file::getExtension(resFile.source.path);
-        return out.str();
-    }
-
     /**
      * Creates a SymbolTable that loads symbols from the various APKs and caches the
      * results for faster lookup.
@@ -425,45 +409,28 @@
             return false;
         }
 
-        if (!mTableMerger->merge(file->getSource(), table.get(), override)) {
-            return false;
+        bool result = false;
+        if (override) {
+            result = mTableMerger->mergeOverlay(file->getSource(), table.get());
+        } else {
+            result = mTableMerger->merge(file->getSource(), table.get());
         }
-        return true;
+        return result;
     }
 
-    bool mergeCompiledFile(io::IFile* file, std::unique_ptr<ResourceFile> fileDesc, bool override) {
-        // Apply the package name used for this compilation phase if none was specified.
-        if (fileDesc->name.package.empty()) {
-            fileDesc->name.package = mContext.getCompilationPackage().toString();
+    bool mergeCompiledFile(io::IFile* file, std::unique_ptr<ResourceFile> fileDesc, bool overlay) {
+        if (mOptions.verbose) {
+            mContext.getDiagnostics()->note(DiagMessage() << "adding " << file->getSource());
         }
 
-        // Mangle the name if necessary.
-        ResourceNameRef resName = fileDesc->name;
-        Maybe<ResourceName> mangledName = mContext.getNameMangler()->mangleName(fileDesc->name);
-        if (mangledName) {
-            resName = mangledName.value();
-        }
-
-        // If we are overriding resources, we supply a custom resolver function.
-        std::function<int(Value*,Value*)> resolver;
-        if (override) {
-            resolver = [](Value* a, Value* b) -> int {
-                int result = ResourceTable::resolveValueCollision(a, b);
-                if (result == 0) {
-                    // Always accept the new value if it would normally conflict (override).
-                    result = 1;
-                }
-                return result;
-            };
+        bool result = false;
+        if (overlay) {
+            result = mTableMerger->mergeFileOverlay(*fileDesc, file);
         } else {
-            // Otherwise use the default resolution.
-            resolver = ResourceTable::resolveValueCollision;
+            result = mTableMerger->mergeFile(*fileDesc, file);
         }
 
-        // Add this file to the table.
-        if (!mFinalTable.addFileReference(resName, fileDesc->config, fileDesc->source,
-                                          util::utf8ToUtf16(buildResourceFileName(*fileDesc)),
-                                          resolver, mContext.getDiagnostics())) {
+        if (!result) {
             return false;
         }
 
@@ -489,10 +456,6 @@
                 return false;
             }
         }
-
-        // Now add this file for later processing. Once the table is assigned IDs, we can compile
-        // this file.
-        mFilesToProcess.insert(FileToProcess{ std::move(fileDesc), file });
         return true;
     }
 
@@ -509,8 +472,8 @@
         }
 
         bool error = false;
-        for (const std::unique_ptr<io::IFile>& file : *collection) {
-            if (!processFile(file.get(), override)) {
+        for (auto iter = collection->iterator(); iter->hasNext(); ) {
+            if (!processFile(iter->next(), override)) {
                 error = true;
             }
         }
@@ -588,7 +551,9 @@
             return 1;
         }
 
-        mTableMerger = util::make_unique<TableMerger>(&mContext, &mFinalTable);
+        TableMergerOptions tableMergerOptions;
+        tableMergerOptions.autoAddOverlay = mOptions.autoAddOverlay;
+        mTableMerger = util::make_unique<TableMerger>(&mContext, &mFinalTable, tableMergerOptions);
 
         if (mOptions.verbose) {
             mContext.getDiagnostics()->note(
@@ -698,31 +663,47 @@
             return 1;
         }
 
-        for (const FileToProcess& file : mFilesToProcess) {
-            const StringPiece path = file.file->getSource().path;
+        for (auto& mergeEntry : mTableMerger->getFilesToMerge()) {
+            const ResourceKeyRef& key = mergeEntry.first;
+            const FileToMerge& fileToMerge = mergeEntry.second;
 
-            if (file.fileExport->name.type != ResourceType::kRaw &&
-                    util::stringEndsWith<char>(path, ".xml.flat")) {
+            const StringPiece path = fileToMerge.file->getSource().path;
+
+            if (key.name.type != ResourceType::kRaw &&
+                    (util::stringEndsWith<char>(path, ".xml.flat") ||
+                    util::stringEndsWith<char>(path, ".xml"))) {
                 if (mOptions.verbose) {
                     mContext.getDiagnostics()->note(DiagMessage() << "linking " << path);
                 }
 
-                std::unique_ptr<io::IData> data = file.file->openAsData();
+                io::IFile* file = fileToMerge.file;
+                std::unique_ptr<io::IData> data = file->openAsData();
                 if (!data) {
-                    mContext.getDiagnostics()->error(DiagMessage(file.file->getSource())
+                    mContext.getDiagnostics()->error(DiagMessage(file->getSource())
                                                      << "failed to open file");
                     return 1;
                 }
 
-                std::unique_ptr<xml::XmlResource> xmlRes = loadBinaryXmlSkipFileExport(
-                        file.file->getSource(), data->data(), data->size(),
-                        mContext.getDiagnostics());
+                std::unique_ptr<xml::XmlResource> xmlRes;
+                if (util::stringEndsWith<char>(path, ".flat")) {
+                    xmlRes = loadBinaryXmlSkipFileExport(file->getSource(),
+                                                         data->data(), data->size(),
+                                                         mContext.getDiagnostics());
+                } else {
+                    xmlRes = xml::inflate(data->data(), data->size(), mContext.getDiagnostics(),
+                                          file->getSource());
+                }
+
                 if (!xmlRes) {
                     return 1;
                 }
 
-                // Move the file description over.
-                xmlRes->file = std::move(*file.fileExport);
+                // Create the file description header.
+                xmlRes->file = ResourceFile{
+                        key.name.toResourceName(),
+                        key.config,
+                        fileToMerge.originalSource,
+                };
 
                 XmlReferenceLinker xmlLinker;
                 if (xmlLinker.consume(&mContext, xmlRes.get())) {
@@ -736,7 +717,7 @@
                         maxSdkLevel = std::max<size_t>(xmlRes->file.config.sdkVersion, 1u);
                     }
 
-                    if (!flattenXml(xmlRes.get(), buildResourceFileName(xmlRes->file), maxSdkLevel,
+                    if (!flattenXml(xmlRes.get(), fileToMerge.dstPath, maxSdkLevel,
                                     archiveWriter.get())) {
                         error = true;
                     }
@@ -750,19 +731,23 @@
                                                                     xmlRes->file.config,
                                                                     sdkLevel)) {
                                 xmlRes->file.config.sdkVersion = sdkLevel;
+
+                                std::string genResourcePath = ResourceUtils::buildResourceFileName(
+                                        xmlRes->file, mContext.getNameMangler());
+
                                 bool added = mFinalTable.addFileReference(
                                         xmlRes->file.name,
                                         xmlRes->file.config,
                                         xmlRes->file.source,
-                                        util::utf8ToUtf16(buildResourceFileName(xmlRes->file)),
+                                        util::utf8ToUtf16(genResourcePath),
                                         mContext.getDiagnostics());
                                 if (!added) {
                                     error = true;
                                     continue;
                                 }
 
-                                if (!flattenXml(xmlRes.get(), buildResourceFileName(xmlRes->file),
-                                                sdkLevel, archiveWriter.get())) {
+                                if (!flattenXml(xmlRes.get(), genResourcePath, sdkLevel,
+                                                archiveWriter.get())) {
                                     error = true;
                                 }
                             }
@@ -777,7 +762,7 @@
                     mContext.getDiagnostics()->note(DiagMessage() << "copying " << path);
                 }
 
-                if (!copyFileToArchive(file.file, buildResourceFileName(*file.fileExport), 0,
+                if (!copyFileToArchive(fileToMerge.file, fileToMerge.dstPath, 0,
                                        archiveWriter.get())) {
                     error = true;
                 }
@@ -845,15 +830,7 @@
 
         if (mOptions.verbose) {
             Debug::printTable(&mFinalTable);
-            for (; !mTableMerger->getFileMergeQueue()->empty();
-                    mTableMerger->getFileMergeQueue()->pop()) {
-                const FileToMerge& f = mTableMerger->getFileMergeQueue()->front();
-                mContext.getDiagnostics()->note(
-                        DiagMessage() << f.srcPath << " -> " << f.dstPath << " from (0x"
-                                      << std::hex << (uintptr_t) f.srcTable << std::dec);
-            }
         }
-
         return 0;
     }
 
@@ -861,24 +838,15 @@
     LinkOptions mOptions;
     LinkContext mContext;
     ResourceTable mFinalTable;
+
+    ResourceTable mLocalFileTable;
     std::unique_ptr<TableMerger> mTableMerger;
 
+    // A pointer to the FileCollection representing the filesystem (not archives).
     io::FileCollection* mFileCollection;
+
+    // A vector of IFileCollections. This is mainly here to keep ownership of the collections.
     std::vector<std::unique_ptr<io::IFileCollection>> mCollections;
-
-    struct FileToProcess {
-        std::unique_ptr<ResourceFile> fileExport;
-        io::IFile* file;
-    };
-
-    struct FileToProcessComparator {
-        bool operator()(const FileToProcess& a, const FileToProcess& b) {
-            return std::tie(a.fileExport->name, a.fileExport->config) <
-                    std::tie(b.fileExport->name, b.fileExport->config);
-        }
-    };
-
-    std::set<FileToProcess, FileToProcessComparator> mFilesToProcess;
 };
 
 int link(const std::vector<StringPiece>& args) {
@@ -915,6 +883,8 @@
                           "package name", &privateSymbolsPackage)
             .optionalFlagList("--extra-packages", "Generate the same R.java but with different "
                               "package names", &extraJavaPackages)
+            .optionalSwitch("--auto-add-overlay", "Allows the addition of new resources in "
+                            "overlays without <add-resource> tags", &options.autoAddOverlay)
             .optionalSwitch("-v", "Enables verbose logging", &options.verbose);
 
     if (!flags.parse("aapt2 link", args, &std::cerr)) {
diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp
index a06a1bf..27a23bd 100644
--- a/tools/aapt2/link/TableMerger.cpp
+++ b/tools/aapt2/link/TableMerger.cpp
@@ -15,6 +15,7 @@
  */
 
 #include "ResourceTable.h"
+#include "ResourceUtils.h"
 #include "ResourceValues.h"
 #include "ValueVisitor.h"
 
@@ -26,8 +27,9 @@
 
 namespace aapt {
 
-TableMerger::TableMerger(IAaptContext* context, ResourceTable* outTable) :
-        mContext(context), mMasterTable(outTable) {
+TableMerger::TableMerger(IAaptContext* context, ResourceTable* outTable,
+                         const TableMergerOptions& options) :
+        mContext(context), mMasterTable(outTable), mOptions(options) {
     // Create the desired package that all tables will be merged into.
     mMasterPackage = mMasterTable->createPackage(
             mContext->getCompilationPackage(), mContext->getPackageId());
@@ -37,7 +39,8 @@
 /**
  * This will merge packages with the same package name (or no package name).
  */
-bool TableMerger::merge(const Source& src, ResourceTable* table, bool overrideExisting) {
+bool TableMerger::mergeImpl(const Source& src, ResourceTable* table,
+                            bool overlay, bool allowNew) {
     const uint8_t desiredPackageId = mContext->getPackageId();
 
     bool error = false;
@@ -55,19 +58,26 @@
             // mangled, then looked up at resolution time.
             // Also, when linking, we convert references with no package name to use
             // the compilation package name.
-            if (!doMerge(src, table, package.get(), false, overrideExisting)) {
-                error = true;
-            }
+            error |= !doMerge(src, table, package.get(),
+                              false /* mangle */, overlay, allowNew, {});
         }
     }
     return !error;
 }
 
+bool TableMerger::merge(const Source& src, ResourceTable* table) {
+    return mergeImpl(src, table, false /* overlay */, true /* allow new */);
+}
+
+bool TableMerger::mergeOverlay(const Source& src, ResourceTable* table) {
+    return mergeImpl(src, table, true /* overlay */, mOptions.autoAddOverlay);
+}
+
 /**
  * This will merge and mangle resources from a static library.
  */
 bool TableMerger::mergeAndMangle(const Source& src, const StringPiece16& packageName,
-                                 ResourceTable* table) {
+                                 ResourceTable* table, io::IFileCollection* collection) {
     bool error = false;
     for (auto& package : table->packages) {
         // Warn of packages with an unrelated ID.
@@ -79,16 +89,35 @@
 
         bool mangle = packageName != mContext->getCompilationPackage();
         mMergedPackages.insert(package->name);
-        if (!doMerge(src, table, package.get(), mangle, false)) {
-            error = true;
-        }
+
+        auto callback = [&](const ResourceNameRef& name, const ConfigDescription& config,
+                            FileReference* newFile, FileReference* oldFile) -> bool {
+            // The old file's path points inside the APK, so we can use it as is.
+            io::IFile* f = collection->findFile(util::utf16ToUtf8(*oldFile->path));
+            if (!f) {
+                mContext->getDiagnostics()->error(DiagMessage(src) << "file '" << *oldFile->path
+                                                  << "' not found");
+                return false;
+            }
+
+            mFilesToMerge[ResourceKeyRef{ name, config }] = FileToMerge{
+                    f, oldFile->getSource(), util::utf16ToUtf8(*newFile->path) };
+            return true;
+        };
+
+        error |= !doMerge(src, table, package.get(),
+                          mangle, false /* overlay */, true /* allow new */, callback);
     }
     return !error;
 }
 
-bool TableMerger::doMerge(const Source& src, ResourceTable* srcTable,
-                          ResourceTablePackage* srcPackage, const bool manglePackage,
-                          const bool overrideExisting) {
+bool TableMerger::doMerge(const Source& src,
+                          ResourceTable* srcTable,
+                          ResourceTablePackage* srcPackage,
+                          const bool manglePackage,
+                          const bool overlay,
+                          const bool allowNewResources,
+                          FileMergeCallback callback) {
     bool error = false;
 
     for (auto& srcType : srcPackage->types) {
@@ -112,10 +141,33 @@
         for (auto& srcEntry : srcType->entries) {
             ResourceEntry* dstEntry;
             if (manglePackage) {
-                dstEntry = dstType->findOrCreateEntry(NameMangler::mangleEntry(
-                        srcPackage->name, srcEntry->name));
+                std::u16string mangledName = NameMangler::mangleEntry(srcPackage->name,
+                                                                      srcEntry->name);
+                if (allowNewResources) {
+                    dstEntry = dstType->findOrCreateEntry(mangledName);
+                } else {
+                    dstEntry = dstType->findEntry(mangledName);
+                }
             } else {
-                dstEntry = dstType->findOrCreateEntry(srcEntry->name);
+                if (allowNewResources) {
+                    dstEntry = dstType->findOrCreateEntry(srcEntry->name);
+                } else {
+                    dstEntry = dstType->findEntry(srcEntry->name);
+                }
+            }
+
+            if (!dstEntry) {
+                mContext->getDiagnostics()->error(DiagMessage(src)
+                                                  << "resource "
+                                                  << ResourceNameRef(srcPackage->name,
+                                                                     srcType->type,
+                                                                     srcEntry->name)
+                                                  << " does not override an existing resource");
+                mContext->getDiagnostics()->note(DiagMessage(src)
+                                                 << "define an <add-resource> tag or use "
+                                                    "--auto-add-overlay");
+                error = true;
+                continue;
             }
 
             if (srcEntry->symbolStatus.state != SymbolState::kUndefined) {
@@ -143,6 +195,8 @@
                 }
             }
 
+            ResourceNameRef resName(mMasterPackage->name, dstType->type, dstEntry->name);
+
             for (ResourceConfigValue& srcValue : srcEntry->values) {
                 auto iter = std::lower_bound(dstEntry->values.begin(), dstEntry->values.end(),
                                              srcValue.config, cmp::lessThanConfig);
@@ -150,7 +204,7 @@
                 if (iter != dstEntry->values.end() && iter->config == srcValue.config) {
                     const int collisionResult = ResourceTable::resolveValueCollision(
                             iter->value.get(), srcValue.value.get());
-                    if (collisionResult == 0 && !overrideExisting) {
+                    if (collisionResult == 0 && !overlay) {
                         // Error!
                         ResourceNameRef resourceName(srcPackage->name,
                                                      srcType->type,
@@ -175,10 +229,26 @@
                     iter = dstEntry->values.insert(iter, ResourceConfigValue{ srcValue.config });
                 }
 
-                if (manglePackage) {
-                    iter->value = cloneAndMangle(srcTable, srcPackage->name, srcValue.value.get());
+                if (FileReference* f = valueCast<FileReference>(srcValue.value.get())) {
+                    std::unique_ptr<FileReference> newFileRef;
+                    if (manglePackage) {
+                        newFileRef = cloneAndMangleFile(srcPackage->name, *f);
+                    } else {
+                        newFileRef = std::unique_ptr<FileReference>(f->clone(
+                                &mMasterTable->stringPool));
+                    }
+
+                    if (callback) {
+                        if (!callback(resName, iter->config, newFileRef.get(), f)) {
+                            error = true;
+                            continue;
+                        }
+                    }
+                    iter->value = std::move(newFileRef);
+
                 } else {
-                    iter->value = clone(srcValue.value.get());
+                    iter->value = std::unique_ptr<Value>(srcValue.value->clone(
+                            &mMasterTable->stringPool));
                 }
             }
         }
@@ -186,28 +256,52 @@
     return !error;
 }
 
-std::unique_ptr<Value> TableMerger::cloneAndMangle(ResourceTable* table,
-                                                   const std::u16string& package,
-                                                   Value* value) {
-    if (FileReference* f = valueCast<FileReference>(value)) {
-        // Mangle the path.
-        StringPiece16 prefix, entry, suffix;
-        if (util::extractResFilePathParts(*f->path, &prefix, &entry, &suffix)) {
-            std::u16string mangledEntry = NameMangler::mangleEntry(package, entry.toString());
-            std::u16string newPath = prefix.toString() + mangledEntry + suffix.toString();
-            mFilesToMerge.push(FileToMerge{ table, *f->path, newPath });
-            std::unique_ptr<FileReference> fileRef = util::make_unique<FileReference>(
-                    mMasterTable->stringPool.makeRef(newPath));
-            fileRef->setComment(f->getComment());
-            fileRef->setSource(f->getSource());
-            return std::move(fileRef);
-        }
+std::unique_ptr<FileReference> TableMerger::cloneAndMangleFile(const std::u16string& package,
+                                                               const FileReference& fileRef) {
+
+    StringPiece16 prefix, entry, suffix;
+    if (util::extractResFilePathParts(*fileRef.path, &prefix, &entry, &suffix)) {
+        std::u16string mangledEntry = NameMangler::mangleEntry(package, entry.toString());
+        std::u16string newPath = prefix.toString() + mangledEntry + suffix.toString();
+        std::unique_ptr<FileReference> newFileRef = util::make_unique<FileReference>(
+                mMasterTable->stringPool.makeRef(newPath));
+        newFileRef->setComment(fileRef.getComment());
+        newFileRef->setSource(fileRef.getSource());
+        return newFileRef;
     }
-    return clone(value);
+    return std::unique_ptr<FileReference>(fileRef.clone(&mMasterTable->stringPool));
 }
 
-std::unique_ptr<Value> TableMerger::clone(Value* value) {
-    return std::unique_ptr<Value>(value->clone(&mMasterTable->stringPool));
+bool TableMerger::mergeFileImpl(const ResourceFile& fileDesc, io::IFile* file, bool overlay) {
+    ResourceTable table;
+    std::u16string path = util::utf8ToUtf16(ResourceUtils::buildResourceFileName(fileDesc,
+                                                                                 nullptr));
+    std::unique_ptr<FileReference> fileRef = util::make_unique<FileReference>(
+            table.stringPool.makeRef(path));
+    fileRef->setSource(fileDesc.source);
+
+    ResourceTablePackage* pkg = table.createPackage(fileDesc.name.package, 0x0);
+    pkg->findOrCreateType(fileDesc.name.type)
+            ->findOrCreateEntry(fileDesc.name.entry)
+            ->values.push_back(ResourceConfigValue{ fileDesc.config, std::move(fileRef) });
+
+    auto callback = [&](const ResourceNameRef& name, const ConfigDescription& config,
+                       FileReference* newFile, FileReference* oldFile) -> bool {
+        mFilesToMerge[ResourceKeyRef{ name, config }] = FileToMerge{
+                file, oldFile->getSource(), util::utf16ToUtf8(*newFile->path) };
+        return true;
+    };
+
+    return doMerge(file->getSource(), &table, pkg,
+                   false /* mangle */, overlay /* overlay */, true /* allow new */, callback);
+}
+
+bool TableMerger::mergeFile(const ResourceFile& fileDesc, io::IFile* file) {
+    return mergeFileImpl(fileDesc, file, false /* overlay */);
+}
+
+bool TableMerger::mergeFileOverlay(const ResourceFile& fileDesc, io::IFile* file) {
+    return mergeFileImpl(fileDesc, file, true /* overlay */);
 }
 
 } // namespace aapt
diff --git a/tools/aapt2/link/TableMerger.h b/tools/aapt2/link/TableMerger.h
index a2c9dbf..e1be5d5 100644
--- a/tools/aapt2/link/TableMerger.h
+++ b/tools/aapt2/link/TableMerger.h
@@ -17,21 +17,40 @@
 #ifndef AAPT_TABLEMERGER_H
 #define AAPT_TABLEMERGER_H
 
+#include "Resource.h"
 #include "ResourceTable.h"
 #include "ResourceValues.h"
+#include "io/File.h"
+#include "process/IResourceTableConsumer.h"
 #include "util/Util.h"
 
-#include "process/IResourceTableConsumer.h"
-
-#include <queue>
-#include <set>
+#include <functional>
+#include <map>
 
 namespace aapt {
 
 struct FileToMerge {
-    ResourceTable* srcTable;
-    std::u16string srcPath;
-    std::u16string dstPath;
+    /**
+     * The compiled file from which to read the data.
+     */
+    io::IFile* file;
+
+    /**
+     * Where the original, uncompiled file came from.
+     */
+    Source originalSource;
+
+    /**
+     * The destination path within the APK/archive.
+     */
+    std::string dstPath;
+};
+
+struct TableMergerOptions {
+    /**
+     * If true, resources in overlays can be added without previously having existed.
+     */
+    bool autoAddOverlay = false;
 };
 
 /**
@@ -50,40 +69,74 @@
  */
 class TableMerger {
 public:
-    TableMerger(IAaptContext* context, ResourceTable* outTable);
+    /**
+     * Note: The outTable ResourceTable must live longer than this TableMerger. References
+     * are made to this ResourceTable for efficiency reasons.
+     */
+    TableMerger(IAaptContext* context, ResourceTable* outTable, const TableMergerOptions& options);
 
-    inline std::queue<FileToMerge>* getFileMergeQueue() {
-        return &mFilesToMerge;
+    const std::map<ResourceKeyRef, FileToMerge>& getFilesToMerge() {
+        return mFilesToMerge;
     }
 
-    inline const std::set<std::u16string>& getMergedPackages() const {
+    const std::set<std::u16string>& getMergedPackages() const {
         return mMergedPackages;
     }
 
     /**
      * Merges resources from the same or empty package. This is for local sources.
      */
-    bool merge(const Source& src, ResourceTable* table, bool overrideExisting);
+    bool merge(const Source& src, ResourceTable* table);
+
+    /**
+     * Merges resources from an overlay ResourceTable.
+     */
+    bool mergeOverlay(const Source& src, ResourceTable* table);
 
     /**
      * Merges resources from the given package, mangling the name. This is for static libraries.
+     * An io::IFileCollection is needed in order to find the referenced Files and process them.
      */
-    bool mergeAndMangle(const Source& src, const StringPiece16& package, ResourceTable* table);
+    bool mergeAndMangle(const Source& src, const StringPiece16& package, ResourceTable* table,
+                        io::IFileCollection* collection);
+
+    /**
+     * Merges a compiled file that belongs to this same or empty package. This is for local sources.
+     */
+    bool mergeFile(const ResourceFile& fileDesc, io::IFile* file);
+
+    /**
+     * Merges a compiled file from an overlay, overriding an existing definition.
+     */
+    bool mergeFileOverlay(const ResourceFile& fileDesc, io::IFile* file);
 
 private:
+    using FileMergeCallback = std::function<bool(const ResourceNameRef&,
+                                                 const ConfigDescription& config,
+                                                 FileReference*,
+                                                 FileReference*)>;
+
     IAaptContext* mContext;
     ResourceTable* mMasterTable;
+    TableMergerOptions mOptions;
     ResourceTablePackage* mMasterPackage;
 
     std::set<std::u16string> mMergedPackages;
-    std::queue<FileToMerge> mFilesToMerge;
+    std::map<ResourceKeyRef, FileToMerge> mFilesToMerge;
+
+    bool mergeFileImpl(const ResourceFile& fileDesc, io::IFile* file, bool overlay);
+
+    bool mergeImpl(const Source& src, ResourceTable* srcTable,
+                   bool overlay, bool allowNew);
 
     bool doMerge(const Source& src, ResourceTable* srcTable, ResourceTablePackage* srcPackage,
-                 const bool manglePackage, const bool overrideExisting);
+                 const bool manglePackage,
+                 const bool overlay,
+                 const bool allowNewResources,
+                 FileMergeCallback callback);
 
-    std::unique_ptr<Value> cloneAndMangle(ResourceTable* table, const std::u16string& package,
-                                          Value* value);
-    std::unique_ptr<Value> clone(Value* value);
+    std::unique_ptr<FileReference> cloneAndMangleFile(const std::u16string& package,
+                                                      const FileReference& value);
 };
 
 } // namespace aapt
diff --git a/tools/aapt2/link/TableMerger_test.cpp b/tools/aapt2/link/TableMerger_test.cpp
index b7ffba7..fa4afd3 100644
--- a/tools/aapt2/link/TableMerger_test.cpp
+++ b/tools/aapt2/link/TableMerger_test.cpp
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
+#include "io/FileSystem.h"
 #include "link/TableMerger.h"
-
 #include "test/Builders.h"
 #include "test/Context.h"
 
@@ -57,10 +57,11 @@
             .build();
 
     ResourceTable finalTable;
-    TableMerger merger(mContext.get(), &finalTable);
+    TableMerger merger(mContext.get(), &finalTable, TableMergerOptions{});
+    io::FileCollection collection;
 
-    ASSERT_TRUE(merger.merge({}, tableA.get(), false));
-    ASSERT_TRUE(merger.mergeAndMangle({}, u"com.app.b", tableB.get()));
+    ASSERT_TRUE(merger.merge({}, tableA.get()));
+    ASSERT_TRUE(merger.mergeAndMangle({}, u"com.app.b", tableB.get(), &collection));
 
     EXPECT_TRUE(merger.getMergedPackages().count(u"com.app.b") != 0);
 
@@ -76,6 +77,60 @@
     AAPT_EXPECT_TRUE(finalTable.findResource(test::parseNameOrDie(u"@com.app.a:id/com.app.b$foo")));
 }
 
+TEST_F(TableMergerTest, MergeFile) {
+    ResourceTable finalTable;
+    TableMergerOptions options;
+    options.autoAddOverlay = false;
+    TableMerger merger(mContext.get(), &finalTable, options);
+
+    ResourceFile fileDesc;
+    fileDesc.config = test::parseConfigOrDie("hdpi-v4");
+    fileDesc.name = test::parseNameOrDie(u"@layout/main");
+    fileDesc.source = Source("res/layout-hdpi/main.xml");
+    test::TestFile testFile("path/to/res/layout-hdpi/main.xml.flat");
+
+    ASSERT_TRUE(merger.mergeFile(fileDesc, &testFile));
+
+    FileReference* file = test::getValueForConfig<FileReference>(&finalTable,
+                                                                 u"@com.app.a:layout/main",
+                                                                 test::parseConfigOrDie("hdpi-v4"));
+    ASSERT_NE(nullptr, file);
+    EXPECT_EQ(std::u16string(u"res/layout-hdpi-v4/main.xml"), *file->path);
+
+    ResourceName name = test::parseNameOrDie(u"@com.app.a:layout/main");
+    ResourceKeyRef key = { name, test::parseConfigOrDie("hdpi-v4") };
+
+    auto iter = merger.getFilesToMerge().find(key);
+    ASSERT_NE(merger.getFilesToMerge().end(), iter);
+
+    const FileToMerge& actualFileToMerge = iter->second;
+    EXPECT_EQ(&testFile, actualFileToMerge.file);
+    EXPECT_EQ(std::string("res/layout-hdpi-v4/main.xml"), actualFileToMerge.dstPath);
+}
+
+TEST_F(TableMergerTest, MergeFileOverlay) {
+    ResourceTable finalTable;
+    TableMergerOptions tableMergerOptions;
+    tableMergerOptions.autoAddOverlay = false;
+    TableMerger merger(mContext.get(), &finalTable, tableMergerOptions);
+
+    ResourceFile fileDesc;
+    fileDesc.name = test::parseNameOrDie(u"@xml/foo");
+    test::TestFile fileA("path/to/fileA.xml.flat");
+    test::TestFile fileB("path/to/fileB.xml.flat");
+
+    ASSERT_TRUE(merger.mergeFile(fileDesc, &fileA));
+    ASSERT_TRUE(merger.mergeFileOverlay(fileDesc, &fileB));
+
+    ResourceName name = test::parseNameOrDie(u"@com.app.a:xml/foo");
+    ResourceKeyRef key = { name, ConfigDescription{} };
+    auto iter = merger.getFilesToMerge().find(key);
+    ASSERT_NE(merger.getFilesToMerge().end(), iter);
+
+    const FileToMerge& actualFileToMerge = iter->second;
+    EXPECT_EQ(&fileB, actualFileToMerge.file);
+}
+
 TEST_F(TableMergerTest, MergeFileReferences) {
     std::unique_ptr<ResourceTable> tableA = test::ResourceTableBuilder()
             .setPackageId(u"com.app.a", 0x7f)
@@ -87,10 +142,12 @@
             .build();
 
     ResourceTable finalTable;
-    TableMerger merger(mContext.get(), &finalTable);
+    TableMerger merger(mContext.get(), &finalTable, TableMergerOptions{});
+    io::FileCollection collection;
+    collection.insertFile("res/xml/file.xml");
 
-    ASSERT_TRUE(merger.merge({}, tableA.get(), false));
-    ASSERT_TRUE(merger.mergeAndMangle({}, u"com.app.b", tableB.get()));
+    ASSERT_TRUE(merger.merge({}, tableA.get()));
+    ASSERT_TRUE(merger.mergeAndMangle({}, u"com.app.b", tableB.get(), &collection));
 
     FileReference* f = test::getValue<FileReference>(&finalTable, u"@com.app.a:xml/file");
     ASSERT_NE(f, nullptr);
@@ -100,13 +157,90 @@
     ASSERT_NE(f, nullptr);
     EXPECT_EQ(std::u16string(u"res/xml/com.app.b$file.xml"), *f->path);
 
-    std::queue<FileToMerge>* filesToMerge = merger.getFileMergeQueue();
-    ASSERT_FALSE(filesToMerge->empty());
+    ResourceName name = test::parseNameOrDie(u"@com.app.a:xml/com.app.b$file");
+    ResourceKeyRef key = { name, ConfigDescription{} };
+    auto iter = merger.getFilesToMerge().find(key);
+    ASSERT_NE(merger.getFilesToMerge().end(), iter);
 
-    FileToMerge& fileToMerge = filesToMerge->front();
-    EXPECT_EQ(fileToMerge.srcTable, tableB.get());
-    EXPECT_EQ(fileToMerge.srcPath, u"res/xml/file.xml");
-    EXPECT_EQ(fileToMerge.dstPath, u"res/xml/com.app.b$file.xml");
+    const FileToMerge& actualFileToMerge = iter->second;
+    EXPECT_EQ(Source("res/xml/file.xml"), actualFileToMerge.file->getSource());
+    EXPECT_EQ(std::string("res/xml/com.app.b$file.xml"), actualFileToMerge.dstPath);
+}
+
+TEST_F(TableMergerTest, OverrideResourceWithOverlay) {
+    std::unique_ptr<ResourceTable> base = test::ResourceTableBuilder()
+            .setPackageId(u"", 0x00)
+            .addValue(u"@bool/foo", ResourceUtils::tryParseBool(u"true"))
+            .build();
+    std::unique_ptr<ResourceTable> overlay = test::ResourceTableBuilder()
+            .setPackageId(u"", 0x00)
+            .addValue(u"@bool/foo", ResourceUtils::tryParseBool(u"false"))
+            .build();
+
+    ResourceTable finalTable;
+    TableMergerOptions tableMergerOptions;
+    tableMergerOptions.autoAddOverlay = false;
+    TableMerger merger(mContext.get(), &finalTable, tableMergerOptions);
+
+    ASSERT_TRUE(merger.merge({}, base.get()));
+    ASSERT_TRUE(merger.mergeOverlay({}, overlay.get()));
+
+    BinaryPrimitive* foo = test::getValue<BinaryPrimitive>(&finalTable, u"@com.app.a:bool/foo");
+    ASSERT_NE(nullptr, foo);
+    EXPECT_EQ(0x0u, foo->value.data);
+}
+
+TEST_F(TableMergerTest, MergeAddResourceFromOverlay) {
+    std::unique_ptr<ResourceTable> tableA = test::ResourceTableBuilder()
+            .setPackageId(u"", 0x7f)
+            .setSymbolState(u"@bool/foo", {}, SymbolState::kUndefined)
+            .build();
+    std::unique_ptr<ResourceTable> tableB = test::ResourceTableBuilder()
+            .setPackageId(u"", 0x7f)
+            .addValue(u"@bool/foo", ResourceUtils::tryParseBool(u"true"))
+            .build();
+
+    ResourceTable finalTable;
+    TableMerger merger(mContext.get(), &finalTable, TableMergerOptions{});
+
+    ASSERT_TRUE(merger.merge({}, tableA.get()));
+    ASSERT_TRUE(merger.mergeOverlay({}, tableB.get()));
+}
+
+TEST_F(TableMergerTest, MergeAddResourceFromOverlayWithAutoAddOverlay) {
+    std::unique_ptr<ResourceTable> tableA = test::ResourceTableBuilder()
+            .setPackageId(u"", 0x7f)
+            .build();
+    std::unique_ptr<ResourceTable> tableB = test::ResourceTableBuilder()
+            .setPackageId(u"", 0x7f)
+            .addValue(u"@bool/foo", ResourceUtils::tryParseBool(u"true"))
+            .build();
+
+    ResourceTable finalTable;
+    TableMergerOptions options;
+    options.autoAddOverlay = true;
+    TableMerger merger(mContext.get(), &finalTable, options);
+
+    ASSERT_TRUE(merger.merge({}, tableA.get()));
+    ASSERT_TRUE(merger.mergeOverlay({}, tableB.get()));
+}
+
+TEST_F(TableMergerTest, FailToMergeNewResourceWithoutAutoAddOverlay) {
+    std::unique_ptr<ResourceTable> tableA = test::ResourceTableBuilder()
+            .setPackageId(u"", 0x7f)
+            .build();
+    std::unique_ptr<ResourceTable> tableB = test::ResourceTableBuilder()
+            .setPackageId(u"", 0x7f)
+            .addValue(u"@bool/foo", ResourceUtils::tryParseBool(u"true"))
+            .build();
+
+    ResourceTable finalTable;
+    TableMergerOptions options;
+    options.autoAddOverlay = false;
+    TableMerger merger(mContext.get(), &finalTable, options);
+
+    ASSERT_TRUE(merger.merge({}, tableA.get()));
+    ASSERT_FALSE(merger.mergeOverlay({}, tableB.get()));
 }
 
 } // namespace aapt
diff --git a/tools/aapt2/test/Common.h b/tools/aapt2/test/Common.h
index 6fdaebb..51e2dd4 100644
--- a/tools/aapt2/test/Common.h
+++ b/tools/aapt2/test/Common.h
@@ -22,7 +22,7 @@
 #include "ResourceTable.h"
 #include "ResourceUtils.h"
 #include "ValueVisitor.h"
-
+#include "io/File.h"
 #include "process/IResourceTableConsumer.h"
 #include "util/StringPiece.h"
 
@@ -87,6 +87,22 @@
     return getValueForConfig<T>(table, resName, {});
 }
 
+class TestFile : public io::IFile {
+private:
+    Source mSource;
+
+public:
+    TestFile(const StringPiece& path) : mSource(path) {}
+
+    std::unique_ptr<io::IData> openAsData() override {
+        return {};
+    }
+
+    const Source& getSource() const override {
+        return mSource;
+    }
+};
+
 } // namespace test
 } // namespace aapt
 
diff --git a/tools/aapt2/unflatten/BinaryResourceParser.cpp b/tools/aapt2/unflatten/BinaryResourceParser.cpp
index 5cc7aa7..21e476f 100644
--- a/tools/aapt2/unflatten/BinaryResourceParser.cpp
+++ b/tools/aapt2/unflatten/BinaryResourceParser.cpp
@@ -27,7 +27,7 @@
 
 #include <androidfw/ResourceTypes.h>
 #include <androidfw/TypeWrappers.h>
-#include <base/macros.h>
+#include <android-base/macros.h>
 
 #include <map>
 #include <string>
@@ -447,6 +447,10 @@
         case Public_entry::kPublic:
             symbol.state = SymbolState::kPublic;
             break;
+
+        case Public_entry::kUndefined:
+            symbol.state = SymbolState::kUndefined;
+            break;
         }
 
         if (!mTable->setSymbolStateAllowMangled(name, resId, symbol, mContext->getDiagnostics())) {
diff --git a/tools/aapt2/util/Maybe.h b/tools/aapt2/util/Maybe.h
index aa409ea..10a2803 100644
--- a/tools/aapt2/util/Maybe.h
+++ b/tools/aapt2/util/Maybe.h
@@ -285,6 +285,8 @@
 -> decltype(std::declval<T> == std::declval<U>) {
     if (a && b) {
         return a.value() == b.value();
+    } else if (!a && !b) {
+        return true;
     }
     return false;
 }
diff --git a/tools/aapt2/util/Maybe_test.cpp b/tools/aapt2/util/Maybe_test.cpp
index 9cca40e..5d42dc3 100644
--- a/tools/aapt2/util/Maybe_test.cpp
+++ b/tools/aapt2/util/Maybe_test.cpp
@@ -124,9 +124,12 @@
     Maybe<int> b = 1;
     Maybe<int> c;
 
+    Maybe<int> emptyA, emptyB;
+
     EXPECT_EQ(a, b);
     EXPECT_EQ(b, a);
     EXPECT_NE(a, c);
+    EXPECT_EQ(emptyA, emptyB);
 }
 
 } // namespace aapt
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index ff15f3b..63411b0 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -1365,24 +1365,18 @@
     }
 
     @Override
+    public File getSharedPreferencesPath(String name) {
+        // pass
+        return null;
+    }
+
+    @Override
     public File getFilesDir() {
         // pass
         return null;
     }
 
     @Override
-    public File getDeviceEncryptedFilesDir() {
-        // pass
-        return null;
-    }
-
-    @Override
-    public File getCredentialEncryptedFilesDir() {
-        // pass
-        return null;
-    }
-
-    @Override
     public File getNoBackupFilesDir() {
         // pass
         return null;
@@ -1424,12 +1418,6 @@
     }
 
     @Override
-    public File getSharedPrefsFile(String name) {
-        // pass
-        return null;
-    }
-
-    @Override
     public SharedPreferences getSharedPreferences(String arg0, int arg1) {
         if (mSharedPreferences == null) {
             mSharedPreferences = new BridgeSharedPreferences();
@@ -1646,6 +1634,11 @@
     }
 
     @Override
+    public void sendStickyBroadcastAsUser(Intent intent, UserHandle user, Bundle options) {
+        // pass
+    }
+
+    @Override
     public void sendStickyOrderedBroadcastAsUser(Intent intent,
             UserHandle user, BroadcastReceiver resultReceiver,
             Handler scheduler, int initialCode, String initialData,
@@ -1814,4 +1807,26 @@
         Integer pos = mScrollYPos.get(view);
         return pos != null ? pos : 0;
     }
+
+    @Override
+    public Context createDeviceEncryptedStorageContext() {
+        // pass
+        return null;
+    }
+
+    @Override
+    public Context createCredentialEncryptedStorageContext() {
+        // pass
+        return null;
+    }
+
+    @Override
+    public boolean isDeviceEncryptedStorage() {
+        return false;
+    }
+
+    @Override
+    public boolean isCredentialEncryptedStorage() {
+        return false;
+    }
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
index e3a19e7..bab25c0 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
@@ -16,6 +16,7 @@
 
 package com.android.layoutlib.bridge.android;
 
+import android.annotation.NonNull;
 import android.app.PackageInstallObserver;
 import android.content.ComponentName;
 import android.content.Intent;
@@ -24,6 +25,7 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ContainerEncryptionParams;
+import android.content.pm.EphemeralApplicationInfo;
 import android.content.pm.FeatureInfo;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageDeleteObserver;
@@ -251,6 +253,36 @@
     }
 
     @Override
+    public List<EphemeralApplicationInfo> getEphemeralApplications() {
+        return null;
+    }
+
+    @Override
+    public Drawable getEphemeralApplicationIcon(String packageName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public byte[] getEphemeralCookie() {
+        return new byte[0];
+    }
+
+    @Override
+    public boolean isEphemeralApplication() {
+        return false;
+    }
+
+    @Override
+    public int getEphemeralCookieMaxSizeBytes() {
+        return 0;
+    }
+
+    @Override
+    public boolean setEphemeralCookie(@NonNull byte[] cookie) {
+        return false;
+    }
+
+    @Override
     public String[] getSystemSharedLibraryNames() {
         return new String[0];
     }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
index 26f9000..d797eec 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
@@ -42,10 +42,6 @@
 import java.util.Collections;
 import java.util.List;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
 /**
  * Action to render a given Drawable provided through {@link DrawableParams#getDrawable()}.
  *
@@ -72,8 +68,12 @@
         BridgeContext context = getContext();
         drawableResource = context.getRenderResources().resolveResValue(drawableResource);
 
-        if (drawableResource == null ||
-                drawableResource.getResourceType() != ResourceType.DRAWABLE) {
+        if (drawableResource == null) {
+            return Status.ERROR_NOT_A_DRAWABLE.createResult();
+        }
+
+        ResourceType resourceType = drawableResource.getResourceType();
+        if (resourceType != ResourceType.DRAWABLE && resourceType != ResourceType.MIPMAP) {
             return Status.ERROR_NOT_A_DRAWABLE.createResult();
         }