Merge "Add choreographer API to the NDK."
diff --git a/Android.mk b/Android.mk
index f58caac..e94bebb 100644
--- a/Android.mk
+++ b/Android.mk
@@ -97,6 +97,7 @@
 	core/java/android/app/trust/ITrustManager.aidl \
 	core/java/android/app/trust/ITrustListener.aidl \
 	core/java/android/app/backup/IBackupManager.aidl \
+	core/java/android/app/backup/IBackupObserver.aidl \
 	core/java/android/app/backup/IFullBackupRestoreObserver.aidl \
 	core/java/android/app/backup/IRestoreObserver.aidl \
 	core/java/android/app/backup/IRestoreSession.aidl \
diff --git a/api/current.txt b/api/current.txt
index 8cd83fd..4f801cb 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2612,6 +2612,7 @@
 
   public abstract class AccessibilityService extends android.app.Service {
     ctor public AccessibilityService();
+    method public final void disableSelf();
     method public final boolean dispatchGesture(android.accessibilityservice.GestureDescription, android.accessibilityservice.AccessibilityService.GestureResultCallback, android.os.Handler);
     method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
     method public final android.accessibilityservice.AccessibilityService.MagnificationController getMagnificationController();
@@ -8426,6 +8427,8 @@
     field public static final java.lang.String ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL";
     field public static final java.lang.String ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT";
     field public static final java.lang.String ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE";
+    field public static final java.lang.String ACTION_PACKAGES_SUSPENDED = "android.intent.action.PACKAGES_SUSPENDED";
+    field public static final java.lang.String ACTION_PACKAGES_UNSUSPENDED = "android.intent.action.PACKAGES_UNSUSPENDED";
     field public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED";
     field public static final java.lang.String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED";
     field public static final java.lang.String ACTION_PACKAGE_DATA_CLEARED = "android.intent.action.PACKAGE_DATA_CLEARED";
@@ -9332,6 +9335,7 @@
 
   public class LauncherApps {
     method public java.util.List<android.content.pm.LauncherActivityInfo> getActivityList(java.lang.String, android.os.UserHandle);
+    method public android.content.pm.ApplicationInfo getApplicationInfo(java.lang.String, int, android.os.UserHandle);
     method public boolean isActivityEnabled(android.content.ComponentName, android.os.UserHandle);
     method public boolean isPackageEnabled(java.lang.String, android.os.UserHandle);
     method public void registerCallback(android.content.pm.LauncherApps.Callback);
@@ -9348,7 +9352,9 @@
     method public abstract void onPackageChanged(java.lang.String, android.os.UserHandle);
     method public abstract void onPackageRemoved(java.lang.String, android.os.UserHandle);
     method public abstract void onPackagesAvailable(java.lang.String[], android.os.UserHandle, boolean);
+    method public void onPackagesSuspended(java.lang.String[], android.os.UserHandle);
     method public abstract void onPackagesUnavailable(java.lang.String[], android.os.UserHandle, boolean);
+    method public void onPackagesUnsuspended(java.lang.String[], android.os.UserHandle);
   }
 
   public class PackageInfo implements android.os.Parcelable {
@@ -19291,6 +19297,7 @@
     method public void adjustVolume(int, int);
     method public void dispatchMediaKeyEvent(android.view.KeyEvent);
     method public int generateAudioSessionId();
+    method public android.media.AudioRecordConfiguration[] getActiveRecordConfigurations();
     method public android.media.AudioDeviceInfo[] getDevices(int);
     method public int getMode();
     method public java.lang.String getParameters(java.lang.String);
@@ -19313,6 +19320,7 @@
     method public void playSoundEffect(int);
     method public void playSoundEffect(int, float);
     method public void registerAudioDeviceCallback(android.media.AudioDeviceCallback, android.os.Handler);
+    method public void registerAudioRecordingCallback(android.media.AudioManager.AudioRecordingCallback, android.os.Handler);
     method public deprecated void registerMediaButtonEventReceiver(android.content.ComponentName);
     method public deprecated void registerMediaButtonEventReceiver(android.app.PendingIntent);
     method public deprecated void registerRemoteControlClient(android.media.RemoteControlClient);
@@ -19336,6 +19344,7 @@
     method public void stopBluetoothSco();
     method public void unloadSoundEffects();
     method public void unregisterAudioDeviceCallback(android.media.AudioDeviceCallback);
+    method public void unregisterAudioRecordingCallback(android.media.AudioManager.AudioRecordingCallback);
     method public deprecated void unregisterMediaButtonEventReceiver(android.content.ComponentName);
     method public deprecated void unregisterMediaButtonEventReceiver(android.app.PendingIntent);
     method public deprecated void unregisterRemoteControlClient(android.media.RemoteControlClient);
@@ -19432,6 +19441,11 @@
     field public static final deprecated int VIBRATE_TYPE_RINGER = 0; // 0x0
   }
 
+  public static abstract class AudioManager.AudioRecordingCallback {
+    ctor public AudioManager.AudioRecordingCallback();
+    method public void onRecordConfigChanged();
+  }
+
   public static abstract interface AudioManager.OnAudioFocusChangeListener {
     method public abstract void onAudioFocusChange(int);
   }
@@ -19502,6 +19516,14 @@
     method public abstract void onRoutingChanged(android.media.AudioRecord);
   }
 
+  public class AudioRecordConfiguration implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getAudioSessionId();
+    method public int getClientAudioSource();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.media.AudioRecordConfiguration> CREATOR;
+  }
+
   public abstract interface AudioRouting {
     method public abstract void addOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
     method public abstract android.media.AudioDeviceInfo getPreferredDevice();
@@ -20427,6 +20449,7 @@
     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_VISION = "video/dolby-vision";
     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";
@@ -28583,6 +28606,7 @@
     field public static final java.lang.String DISALLOW_OUTGOING_CALLS = "no_outgoing_calls";
     field public static final java.lang.String DISALLOW_REMOVE_USER = "no_remove_user";
     field public static final java.lang.String DISALLOW_SAFE_BOOT = "no_safe_boot";
+    field public static final java.lang.String DISALLOW_SET_USER_ICON = "no_set_user_icon";
     field public static final java.lang.String DISALLOW_SHARE_LOCATION = "no_share_location";
     field public static final java.lang.String DISALLOW_SMS = "no_sms";
     field public static final java.lang.String DISALLOW_UNINSTALL_APPS = "no_uninstall_apps";
@@ -36244,6 +36268,7 @@
     method public java.lang.String getDeviceId(int);
     method public java.lang.String getDeviceSoftwareVersion();
     method public java.lang.String getGroupIdLevel1();
+    method public java.lang.String getIccSimChallengeResponse(int, java.lang.String);
     method public java.lang.String getLine1Number();
     method public java.lang.String getMmsUAProfUrl();
     method public java.lang.String getMmsUserAgent();
@@ -42853,6 +42878,7 @@
     method public android.view.accessibility.AccessibilityNodeInfo.CollectionInfo getCollectionInfo();
     method public android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo getCollectionItemInfo();
     method public java.lang.CharSequence getContentDescription();
+    method public int getDrawingOrder();
     method public java.lang.CharSequence getError();
     method public android.os.Bundle getExtras();
     method public int getInputType();
@@ -42915,6 +42941,7 @@
     method public void setContentInvalid(boolean);
     method public void setContextClickable(boolean);
     method public void setDismissable(boolean);
+    method public void setDrawingOrder(int);
     method public void setEditable(boolean);
     method public void setEnabled(boolean);
     method public void setError(java.lang.CharSequence);
@@ -45702,6 +45729,7 @@
     method public int getBaselineAlignedChildIndex();
     method public android.graphics.drawable.Drawable getDividerDrawable();
     method public int getDividerPadding();
+    method public int getGravity();
     method public int getOrientation();
     method public int getShowDividers();
     method public float getWeightSum();
diff --git a/api/system-current.txt b/api/system-current.txt
index e6ae46a..47a51d4 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -2714,6 +2714,7 @@
 
   public abstract class AccessibilityService extends android.app.Service {
     ctor public AccessibilityService();
+    method public final void disableSelf();
     method public final boolean dispatchGesture(android.accessibilityservice.GestureDescription, android.accessibilityservice.AccessibilityService.GestureResultCallback, android.os.Handler);
     method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
     method public final android.accessibilityservice.AccessibilityService.MagnificationController getMagnificationController();
@@ -2860,6 +2861,7 @@
     method public abstract java.lang.String getAuthTokenLabel(java.lang.String);
     method public final android.os.IBinder getIBinder();
     method public abstract android.os.Bundle hasFeatures(android.accounts.AccountAuthenticatorResponse, android.accounts.Account, java.lang.String[]) throws android.accounts.NetworkErrorException;
+    method public android.os.Bundle isCredentialsUpdateSuggested(android.accounts.AccountAuthenticatorResponse, android.accounts.Account, java.lang.String) throws android.accounts.NetworkErrorException;
     method public android.os.Bundle startAddAccountSession(android.accounts.AccountAuthenticatorResponse, java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle) throws android.accounts.NetworkErrorException;
     method public android.os.Bundle startUpdateCredentialsSession(android.accounts.AccountAuthenticatorResponse, android.accounts.Account, java.lang.String, android.os.Bundle) throws android.accounts.NetworkErrorException;
     method public abstract android.os.Bundle updateCredentials(android.accounts.AccountAuthenticatorResponse, android.accounts.Account, java.lang.String, android.os.Bundle) throws android.accounts.NetworkErrorException;
@@ -2915,6 +2917,7 @@
     method public java.lang.String getUserData(android.accounts.Account, java.lang.String);
     method public android.accounts.AccountManagerFuture<java.lang.Boolean> hasFeatures(android.accounts.Account, java.lang.String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
     method public void invalidateAuthToken(java.lang.String, java.lang.String);
+    method public android.accounts.AccountManagerFuture<java.lang.Boolean> isCredentialsUpdateSuggested(android.accounts.Account, java.lang.String, android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
     method public static deprecated android.content.Intent newChooseAccountIntent(android.accounts.Account, java.util.ArrayList<android.accounts.Account>, java.lang.String[], boolean, java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle);
     method public static android.content.Intent newChooseAccountIntent(android.accounts.Account, java.util.List<android.accounts.Account>, java.lang.String[], java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle);
     method public boolean notifyAccountAuthenticated(android.accounts.Account);
@@ -5938,6 +5941,7 @@
     method public deprecated android.content.ComponentName getDeviceInitializerComponent();
     method public java.lang.String getDeviceOwner();
     method public java.lang.String getDeviceOwnerLockScreenInfo();
+    method public java.lang.String getDeviceOwnerNameOnAnyUser();
     method public java.util.List<byte[]> getInstalledCaCerts(android.content.ComponentName);
     method public int getKeyguardDisabledFeatures(android.content.ComponentName);
     method public java.lang.String getLongSupportMessage(android.content.ComponentName);
@@ -6291,10 +6295,33 @@
     method public java.lang.String getCurrentTransport();
     method public boolean isBackupEnabled();
     method public java.lang.String[] listAllTransports();
+    method public int requestBackup(java.lang.String[], android.app.backup.BackupObserver);
     method public int requestRestore(android.app.backup.RestoreObserver);
     method public java.lang.String selectBackupTransport(java.lang.String);
     method public void setAutoRestore(boolean);
     method public void setBackupEnabled(boolean);
+    field public static final int ERROR_AGENT_FAILURE = -1003; // 0xfffffc15
+    field public static final int ERROR_BACKUP_NOT_ALLOWED = -2001; // 0xfffff82f
+    field public static final int ERROR_PACKAGE_NOT_FOUND = -2002; // 0xfffff82e
+    field public static final int ERROR_TRANSPORT_ABORTED = -1000; // 0xfffffc18
+    field public static final int ERROR_TRANSPORT_PACKAGE_REJECTED = -1002; // 0xfffffc16
+    field public static final int SUCCESS = 0; // 0x0
+  }
+
+  public abstract class BackupObserver {
+    ctor public BackupObserver();
+    method public void backupFinished(int);
+    method public void onResult(java.lang.String, int);
+    method public void onUpdate(java.lang.String, android.app.backup.BackupProgress);
+  }
+
+  public class BackupProgress implements android.os.Parcelable {
+    ctor public BackupProgress(long, long);
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.app.backup.BackupProgress> CREATOR;
+    field public final long bytesExpected;
+    field public final long bytesTransferred;
   }
 
   public class BackupTransport {
@@ -6317,7 +6344,9 @@
     method public int initializeDevice();
     method public java.lang.String name();
     method public android.app.backup.RestoreDescription nextRestorePackage();
+    method public int performBackup(android.content.pm.PackageInfo, android.os.ParcelFileDescriptor, int);
     method public int performBackup(android.content.pm.PackageInfo, android.os.ParcelFileDescriptor);
+    method public int performFullBackup(android.content.pm.PackageInfo, android.os.ParcelFileDescriptor, int);
     method public int performFullBackup(android.content.pm.PackageInfo, android.os.ParcelFileDescriptor);
     method public long requestBackupTime();
     method public long requestFullBackupTime();
@@ -6326,6 +6355,7 @@
     method public java.lang.String transportDirName();
     field public static final int AGENT_ERROR = -1003; // 0xfffffc15
     field public static final int AGENT_UNKNOWN = -1004; // 0xfffffc14
+    field public static final int FLAG_USER_INITIATED = 1; // 0x1
     field public static final int NO_MORE_DATA = -1; // 0xffffffff
     field public static final int TRANSPORT_ERROR = -1000; // 0xfffffc18
     field public static final int TRANSPORT_NOT_INITIALIZED = -1001; // 0xfffffc17
@@ -8696,6 +8726,8 @@
     field public static final java.lang.String ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL";
     field public static final java.lang.String ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT";
     field public static final java.lang.String ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE";
+    field public static final java.lang.String ACTION_PACKAGES_SUSPENDED = "android.intent.action.PACKAGES_SUSPENDED";
+    field public static final java.lang.String ACTION_PACKAGES_UNSUSPENDED = "android.intent.action.PACKAGES_UNSUSPENDED";
     field public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED";
     field public static final java.lang.String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED";
     field public static final java.lang.String ACTION_PACKAGE_DATA_CLEARED = "android.intent.action.PACKAGE_DATA_CLEARED";
@@ -9641,6 +9673,7 @@
 
   public class LauncherApps {
     method public java.util.List<android.content.pm.LauncherActivityInfo> getActivityList(java.lang.String, android.os.UserHandle);
+    method public android.content.pm.ApplicationInfo getApplicationInfo(java.lang.String, int, android.os.UserHandle);
     method public boolean isActivityEnabled(android.content.ComponentName, android.os.UserHandle);
     method public boolean isPackageEnabled(java.lang.String, android.os.UserHandle);
     method public void registerCallback(android.content.pm.LauncherApps.Callback);
@@ -9657,7 +9690,9 @@
     method public abstract void onPackageChanged(java.lang.String, android.os.UserHandle);
     method public abstract void onPackageRemoved(java.lang.String, android.os.UserHandle);
     method public abstract void onPackagesAvailable(java.lang.String[], android.os.UserHandle, boolean);
+    method public void onPackagesSuspended(java.lang.String[], android.os.UserHandle);
     method public abstract void onPackagesUnavailable(java.lang.String[], android.os.UserHandle, boolean);
+    method public void onPackagesUnsuspended(java.lang.String[], android.os.UserHandle);
   }
 
   public class PackageInfo implements android.os.Parcelable {
@@ -20588,6 +20623,7 @@
     method public void adjustVolume(int, int);
     method public void dispatchMediaKeyEvent(android.view.KeyEvent);
     method public int generateAudioSessionId();
+    method public android.media.AudioRecordConfiguration[] getActiveRecordConfigurations();
     method public android.media.AudioDeviceInfo[] getDevices(int);
     method public int getMode();
     method public java.lang.String getParameters(java.lang.String);
@@ -20612,6 +20648,7 @@
     method public void playSoundEffect(int, float);
     method public void registerAudioDeviceCallback(android.media.AudioDeviceCallback, android.os.Handler);
     method public int registerAudioPolicy(android.media.audiopolicy.AudioPolicy);
+    method public void registerAudioRecordingCallback(android.media.AudioManager.AudioRecordingCallback, android.os.Handler);
     method public deprecated void registerMediaButtonEventReceiver(android.content.ComponentName);
     method public deprecated void registerMediaButtonEventReceiver(android.app.PendingIntent);
     method public deprecated void registerRemoteControlClient(android.media.RemoteControlClient);
@@ -20638,6 +20675,7 @@
     method public void unloadSoundEffects();
     method public void unregisterAudioDeviceCallback(android.media.AudioDeviceCallback);
     method public void unregisterAudioPolicyAsync(android.media.audiopolicy.AudioPolicy);
+    method public void unregisterAudioRecordingCallback(android.media.AudioManager.AudioRecordingCallback);
     method public deprecated void unregisterMediaButtonEventReceiver(android.content.ComponentName);
     method public deprecated void unregisterMediaButtonEventReceiver(android.app.PendingIntent);
     method public deprecated void unregisterRemoteControlClient(android.media.RemoteControlClient);
@@ -20737,6 +20775,11 @@
     field public static final deprecated int VIBRATE_TYPE_RINGER = 0; // 0x0
   }
 
+  public static abstract class AudioManager.AudioRecordingCallback {
+    ctor public AudioManager.AudioRecordingCallback();
+    method public void onRecordConfigChanged();
+  }
+
   public static abstract interface AudioManager.OnAudioFocusChangeListener {
     method public abstract void onAudioFocusChange(int);
   }
@@ -20810,6 +20853,14 @@
     method public abstract void onRoutingChanged(android.media.AudioRecord);
   }
 
+  public class AudioRecordConfiguration implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getAudioSessionId();
+    method public int getClientAudioSource();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.media.AudioRecordConfiguration> CREATOR;
+  }
+
   public abstract interface AudioRouting {
     method public abstract void addOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
     method public abstract android.media.AudioDeviceInfo getPreferredDevice();
@@ -21735,6 +21786,7 @@
     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_VISION = "video/dolby-vision";
     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";
@@ -25580,6 +25632,7 @@
   public static class WifiConfiguration.KeyMgmt {
     field public static final int IEEE8021X = 3; // 0x3
     field public static final int NONE = 0; // 0x0
+    field public static final int WPA2_PSK = 4; // 0x4
     field public static final int WPA_EAP = 2; // 0x2
     field public static final int WPA_PSK = 1; // 0x1
     field public static final java.lang.String[] strings;
@@ -25711,6 +25764,8 @@
     method public java.util.List<android.net.wifi.WifiConfiguration> getPrivilegedConfiguredNetworks();
     method public java.util.List<android.net.wifi.ScanInfo> getScanInfos();
     method public java.util.List<android.net.wifi.ScanResult> getScanResults();
+    method public android.net.wifi.WifiConfiguration getWifiApConfiguration();
+    method public int getWifiApState();
     method public int getWifiState();
     method public boolean is5GHzBandSupported();
     method public deprecated boolean isBatchedScanSupported();
@@ -25722,6 +25777,7 @@
     method public boolean isPreferredNetworkOffloadSupported();
     method public boolean isScanAlwaysAvailable();
     method public boolean isTdlsSupported();
+    method public boolean isWifiApEnabled();
     method public boolean isWifiEnabled();
     method public boolean isWifiScannerSupported();
     method public boolean pingSupplicant();
@@ -25732,6 +25788,8 @@
     method public void setOsuSelection(int);
     method public void setTdlsEnabled(java.net.InetAddress, boolean);
     method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
+    method public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration);
+    method public boolean setWifiApEnabled(android.net.wifi.WifiConfiguration, boolean);
     method public boolean setWifiEnabled(boolean);
     method public deprecated boolean startLocationRestrictedScan(android.os.WorkSource);
     method public boolean startScan();
@@ -30601,6 +30659,7 @@
     field public static final java.lang.String DISALLOW_OUTGOING_CALLS = "no_outgoing_calls";
     field public static final java.lang.String DISALLOW_REMOVE_USER = "no_remove_user";
     field public static final java.lang.String DISALLOW_SAFE_BOOT = "no_safe_boot";
+    field public static final java.lang.String DISALLOW_SET_USER_ICON = "no_set_user_icon";
     field public static final java.lang.String DISALLOW_SHARE_LOCATION = "no_share_location";
     field public static final java.lang.String DISALLOW_SMS = "no_sms";
     field public static final java.lang.String DISALLOW_UNINSTALL_APPS = "no_uninstall_apps";
@@ -38589,6 +38648,7 @@
     method public java.lang.String getDeviceId(int);
     method public java.lang.String getDeviceSoftwareVersion();
     method public java.lang.String getGroupIdLevel1();
+    method public java.lang.String getIccSimChallengeResponse(int, java.lang.String);
     method public java.lang.String getLine1Number();
     method public java.lang.String getMmsUAProfUrl();
     method public java.lang.String getMmsUserAgent();
@@ -45246,6 +45306,7 @@
     method public android.view.accessibility.AccessibilityNodeInfo.CollectionInfo getCollectionInfo();
     method public android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo getCollectionItemInfo();
     method public java.lang.CharSequence getContentDescription();
+    method public int getDrawingOrder();
     method public java.lang.CharSequence getError();
     method public android.os.Bundle getExtras();
     method public int getInputType();
@@ -45308,6 +45369,7 @@
     method public void setContentInvalid(boolean);
     method public void setContextClickable(boolean);
     method public void setDismissable(boolean);
+    method public void setDrawingOrder(int);
     method public void setEditable(boolean);
     method public void setEnabled(boolean);
     method public void setError(java.lang.CharSequence);
@@ -46516,6 +46578,18 @@
     method public void proceed();
   }
 
+  public abstract class TokenBindingService {
+    ctor public TokenBindingService();
+    method public abstract void deleteAllKeys(android.webkit.ValueCallback<java.lang.Boolean>);
+    method public abstract void deleteKey(android.net.Uri, android.webkit.ValueCallback<java.lang.Boolean>);
+    method public abstract void enableTokenBinding();
+    method public static android.webkit.TokenBindingService getInstance();
+    method public abstract void getKey(android.net.Uri, java.lang.String, android.webkit.ValueCallback<java.security.KeyPair>);
+    field public static final java.lang.String KEY_ALGORITHM_ECDSAP256 = "ECDSAP256";
+    field public static final java.lang.String KEY_ALGORITHM_RSA2048_PKCS_1_5 = "RSA2048_PKCS_1.5";
+    field public static final java.lang.String KEY_ALGORITHM_RSA2048_PSS = "RSA2048PSS";
+  }
+
   public final class URLUtil {
     ctor public URLUtil();
     method public static java.lang.String composeSearchUrl(java.lang.String, java.lang.String, java.lang.String);
@@ -47138,6 +47212,7 @@
     method public abstract android.webkit.CookieManager getCookieManager();
     method public abstract android.webkit.GeolocationPermissions getGeolocationPermissions();
     method public abstract android.webkit.WebViewFactoryProvider.Statics getStatics();
+    method public abstract android.webkit.TokenBindingService getTokenBindingService();
     method public abstract android.webkit.WebIconDatabase getWebIconDatabase();
     method public abstract android.webkit.WebStorage getWebStorage();
     method public abstract android.webkit.WebViewDatabase getWebViewDatabase(android.content.Context);
@@ -48408,6 +48483,7 @@
     method public int getBaselineAlignedChildIndex();
     method public android.graphics.drawable.Drawable getDividerDrawable();
     method public int getDividerPadding();
+    method public int getGravity();
     method public int getOrientation();
     method public int getShowDividers();
     method public float getWeightSum();
diff --git a/api/test-current.txt b/api/test-current.txt
index 4824f68..6b5b8b0 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -2612,6 +2612,7 @@
 
   public abstract class AccessibilityService extends android.app.Service {
     ctor public AccessibilityService();
+    method public final void disableSelf();
     method public final boolean dispatchGesture(android.accessibilityservice.GestureDescription, android.accessibilityservice.AccessibilityService.GestureResultCallback, android.os.Handler);
     method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
     method public final android.accessibilityservice.AccessibilityService.MagnificationController getMagnificationController();
@@ -8431,6 +8432,8 @@
     field public static final java.lang.String ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL";
     field public static final java.lang.String ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT";
     field public static final java.lang.String ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE";
+    field public static final java.lang.String ACTION_PACKAGES_SUSPENDED = "android.intent.action.PACKAGES_SUSPENDED";
+    field public static final java.lang.String ACTION_PACKAGES_UNSUSPENDED = "android.intent.action.PACKAGES_UNSUSPENDED";
     field public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED";
     field public static final java.lang.String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED";
     field public static final java.lang.String ACTION_PACKAGE_DATA_CLEARED = "android.intent.action.PACKAGE_DATA_CLEARED";
@@ -9339,6 +9342,7 @@
 
   public class LauncherApps {
     method public java.util.List<android.content.pm.LauncherActivityInfo> getActivityList(java.lang.String, android.os.UserHandle);
+    method public android.content.pm.ApplicationInfo getApplicationInfo(java.lang.String, int, android.os.UserHandle);
     method public boolean isActivityEnabled(android.content.ComponentName, android.os.UserHandle);
     method public boolean isPackageEnabled(java.lang.String, android.os.UserHandle);
     method public void registerCallback(android.content.pm.LauncherApps.Callback);
@@ -9355,7 +9359,9 @@
     method public abstract void onPackageChanged(java.lang.String, android.os.UserHandle);
     method public abstract void onPackageRemoved(java.lang.String, android.os.UserHandle);
     method public abstract void onPackagesAvailable(java.lang.String[], android.os.UserHandle, boolean);
+    method public void onPackagesSuspended(java.lang.String[], android.os.UserHandle);
     method public abstract void onPackagesUnavailable(java.lang.String[], android.os.UserHandle, boolean);
+    method public void onPackagesUnsuspended(java.lang.String[], android.os.UserHandle);
   }
 
   public class PackageInfo implements android.os.Parcelable {
@@ -19299,6 +19305,7 @@
     method public void adjustVolume(int, int);
     method public void dispatchMediaKeyEvent(android.view.KeyEvent);
     method public int generateAudioSessionId();
+    method public android.media.AudioRecordConfiguration[] getActiveRecordConfigurations();
     method public android.media.AudioDeviceInfo[] getDevices(int);
     method public int getMode();
     method public java.lang.String getParameters(java.lang.String);
@@ -19321,6 +19328,7 @@
     method public void playSoundEffect(int);
     method public void playSoundEffect(int, float);
     method public void registerAudioDeviceCallback(android.media.AudioDeviceCallback, android.os.Handler);
+    method public void registerAudioRecordingCallback(android.media.AudioManager.AudioRecordingCallback, android.os.Handler);
     method public deprecated void registerMediaButtonEventReceiver(android.content.ComponentName);
     method public deprecated void registerMediaButtonEventReceiver(android.app.PendingIntent);
     method public deprecated void registerRemoteControlClient(android.media.RemoteControlClient);
@@ -19344,6 +19352,7 @@
     method public void stopBluetoothSco();
     method public void unloadSoundEffects();
     method public void unregisterAudioDeviceCallback(android.media.AudioDeviceCallback);
+    method public void unregisterAudioRecordingCallback(android.media.AudioManager.AudioRecordingCallback);
     method public deprecated void unregisterMediaButtonEventReceiver(android.content.ComponentName);
     method public deprecated void unregisterMediaButtonEventReceiver(android.app.PendingIntent);
     method public deprecated void unregisterRemoteControlClient(android.media.RemoteControlClient);
@@ -19440,6 +19449,11 @@
     field public static final deprecated int VIBRATE_TYPE_RINGER = 0; // 0x0
   }
 
+  public static abstract class AudioManager.AudioRecordingCallback {
+    ctor public AudioManager.AudioRecordingCallback();
+    method public void onRecordConfigChanged();
+  }
+
   public static abstract interface AudioManager.OnAudioFocusChangeListener {
     method public abstract void onAudioFocusChange(int);
   }
@@ -19510,6 +19524,14 @@
     method public abstract void onRoutingChanged(android.media.AudioRecord);
   }
 
+  public class AudioRecordConfiguration implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getAudioSessionId();
+    method public int getClientAudioSource();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.media.AudioRecordConfiguration> CREATOR;
+  }
+
   public abstract interface AudioRouting {
     method public abstract void addOnRoutingListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
     method public abstract android.media.AudioDeviceInfo getPreferredDevice();
@@ -20435,6 +20457,7 @@
     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_VISION = "video/dolby-vision";
     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";
@@ -28592,6 +28615,7 @@
     field public static final java.lang.String DISALLOW_OUTGOING_CALLS = "no_outgoing_calls";
     field public static final java.lang.String DISALLOW_REMOVE_USER = "no_remove_user";
     field public static final java.lang.String DISALLOW_SAFE_BOOT = "no_safe_boot";
+    field public static final java.lang.String DISALLOW_SET_USER_ICON = "no_set_user_icon";
     field public static final java.lang.String DISALLOW_SHARE_LOCATION = "no_share_location";
     field public static final java.lang.String DISALLOW_SMS = "no_sms";
     field public static final java.lang.String DISALLOW_UNINSTALL_APPS = "no_uninstall_apps";
@@ -36258,6 +36282,7 @@
     method public java.lang.String getDeviceId(int);
     method public java.lang.String getDeviceSoftwareVersion();
     method public java.lang.String getGroupIdLevel1();
+    method public java.lang.String getIccSimChallengeResponse(int, java.lang.String);
     method public java.lang.String getLine1Number();
     method public java.lang.String getMmsUAProfUrl();
     method public java.lang.String getMmsUserAgent();
@@ -42869,6 +42894,7 @@
     method public android.view.accessibility.AccessibilityNodeInfo.CollectionInfo getCollectionInfo();
     method public android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo getCollectionItemInfo();
     method public java.lang.CharSequence getContentDescription();
+    method public int getDrawingOrder();
     method public java.lang.CharSequence getError();
     method public android.os.Bundle getExtras();
     method public int getInputType();
@@ -42931,6 +42957,7 @@
     method public void setContentInvalid(boolean);
     method public void setContextClickable(boolean);
     method public void setDismissable(boolean);
+    method public void setDrawingOrder(int);
     method public void setEditable(boolean);
     method public void setEnabled(boolean);
     method public void setError(java.lang.CharSequence);
@@ -45718,6 +45745,7 @@
     method public int getBaselineAlignedChildIndex();
     method public android.graphics.drawable.Drawable getDividerDrawable();
     method public int getDividerPadding();
+    method public int getGravity();
     method public int getOrientation();
     method public int getShowDividers();
     method public float getWeightSum();
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 3293c26..8bc17f8 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -541,6 +541,22 @@
     }
 
     /**
+     * This method allows accessibility service turn itself off
+     * and the service will become disabled from the Settings.
+     */
+    public final void disableSelf() {
+        final IAccessibilityServiceConnection connection =
+                AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
+        if (connection != null) {
+            try {
+                connection.disableSelf();
+            } catch (RemoteException re) {
+                throw new RuntimeException(re);
+            }
+        }
+    }
+
+    /**
      * Returns the magnification controller, which may be used to query and
      * modify the state of display magnification.
      * <p>
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index a65b87b..e58ef2f 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -65,6 +65,8 @@
 
     boolean performGlobalAction(int action);
 
+    oneway void disableSelf();
+
     oneway void setOnKeyEventResult(boolean handled, int sequence);
 
     float getMagnificationScale();
diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java
index 690e674..4dca8e2 100644
--- a/core/java/android/accounts/AbstractAccountAuthenticator.java
+++ b/core/java/android/accounts/AbstractAccountAuthenticator.java
@@ -16,16 +16,16 @@
 
 package android.accounts;
 
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.text.TextUtils;
-import android.os.Binder;
-import android.os.IBinder;
-import android.content.pm.PackageManager;
-import android.content.Context;
-import android.content.Intent;
 import android.Manifest;
 import android.annotation.SystemApi;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.text.TextUtils;
 import android.util.Log;
 
 import java.util.Arrays;
@@ -436,6 +436,7 @@
             }
         }
 
+        @Override
         public void finishSession(
                 IAccountAuthenticatorResponse response,
                 String accountType,
@@ -461,6 +462,24 @@
 
             }
         }
+
+        @Override
+        public void isCredentialsUpdateSuggested(
+                IAccountAuthenticatorResponse response,
+                Account account,
+                String statusToken) throws RemoteException {
+            checkBinderPermission();
+            try {
+                final Bundle result = AbstractAccountAuthenticator.this
+                        .isCredentialsUpdateSuggested(
+                                new AccountAuthenticatorResponse(response), account, statusToken);
+                if (result != null) {
+                    response.onResult(result);
+                }
+            } catch (Exception e) {
+                handleException(response, "isCredentialsUpdateSuggested", account.toString(), e);
+            }
+        }
     }
 
     private void handleException(IAccountAuthenticatorResponse response, String method,
@@ -873,7 +892,8 @@
      *         <li>{@link AccountManager#KEY_ERROR_CODE} and
      *         {@link AccountManager#KEY_ERROR_MESSAGE} to indicate an error
      *         </ul>
-     * @throws NetworkErrorException
+     * @throws NetworkErrorException if the authenticator could not honor the request due to a
+     *             network error
      * @see #startAddAccountSession and #startUpdateCredentialsSession
      * @hide
      */
@@ -944,4 +964,32 @@
         // Otherwise, session bundle was created by startAddAccountSession default implementation.
         return addAccount(response, accountType, authTokenType, requiredFeatures, sessionOptions);
     }
+
+    /**
+     * Checks if update of the account credentials is suggested.
+     *
+     * @param response to send the result back to the AccountManager, will never be null.
+     * @param account the account to check, will never be null
+     * @param statusToken a String of token to check if update of credentials is suggested.
+     * @return a Bundle result or null if the result is to be returned via the response. The result
+     *         will contain either:
+     *         <ul>
+     *         <li>{@link AccountManager#KEY_BOOLEAN_RESULT}, true if update of account's
+     *         credentials is suggested, false otherwise
+     *         <li>{@link AccountManager#KEY_ERROR_CODE} and
+     *         {@link AccountManager#KEY_ERROR_MESSAGE} to indicate an error
+     *         </ul>
+     * @throws NetworkErrorException if the authenticator could not honor the request due to a
+     *             network error
+     * @hide
+     */
+    @SystemApi
+    public Bundle isCredentialsUpdateSuggested(
+            final AccountAuthenticatorResponse response,
+            Account account,
+            String statusToken) throws NetworkErrorException {
+        Bundle result = new Bundle();
+        result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);
+        return result;
+    }
 }
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 10f5d0d..259f0da 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -16,6 +16,8 @@
 
 package android.accounts;
 
+import static android.Manifest.permission.GET_ACCOUNTS;
+
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
 import android.annotation.Size;
@@ -54,8 +56,6 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
-import static android.Manifest.permission.GET_ACCOUNTS;
-
 /**
  * This class provides access to a centralized registry of the user's
  * online accounts.  The user enters credentials (username and password) once
@@ -2866,4 +2866,50 @@
             }
         }.start();
     }
+
+    /**
+     * Checks whether {@link #updateCredentials} or {@link #startUpdateCredentialsSession} should be
+     * called with respect to the specified account.
+     * <p>
+     * This method may be called from any thread, but the returned {@link AccountManagerFuture} must
+     * not be used on the main thread.
+     *
+     * @param account The {@link Account} to be checked whether {@link #updateCredentials} or
+     * {@link #startUpdateCredentialsSession} should be called
+     * @param statusToken a String of token to check account staus
+     * @param callback Callback to invoke when the request completes, null for no callback
+     * @param handler {@link Handler} identifying the callback thread, null for the main thread
+     * @return An {@link AccountManagerFuture} which resolves to a Boolean, true if the credentials
+     *         of the account should be updated.
+     * @hide
+     */
+    @SystemApi
+    public AccountManagerFuture<Boolean> isCredentialsUpdateSuggested(
+            final Account account,
+            final String statusToken,
+            AccountManagerCallback<Boolean> callback,
+            Handler handler) {
+        if (account == null) {
+            throw new IllegalArgumentException("account is null");
+        }
+
+        if (TextUtils.isEmpty(statusToken)) {
+            throw new IllegalArgumentException("status token is empty");
+        }
+
+        return new Future2Task<Boolean>(handler, callback) {
+            public void doWork() throws RemoteException {
+                mService.isCredentialsUpdateSuggested(
+                        mResponse,
+                        account,
+                        statusToken);
+            }
+            public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
+                if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) {
+                    throw new AuthenticatorException("no result in response");
+                }
+                return bundle.getBoolean(KEY_BOOLEAN_RESULT);
+            }
+        }.start();
+    }
 }
diff --git a/core/java/android/accounts/IAccountAuthenticator.aidl b/core/java/android/accounts/IAccountAuthenticator.aidl
index 6bda800..8b98ca2 100644
--- a/core/java/android/accounts/IAccountAuthenticator.aidl
+++ b/core/java/android/accounts/IAccountAuthenticator.aidl
@@ -104,4 +104,10 @@
      */
     void finishSession(in IAccountAuthenticatorResponse response, String accountType,
         in Bundle sessionBundle);
+
+    /**
+     * Checks if the credentials of the provided account should be updated.
+     */
+    void isCredentialsUpdateSuggested(in IAccountAuthenticatorResponse response, in Account account,
+        String statusToken);
 }
diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl
index 608501f..39dedf4 100644
--- a/core/java/android/accounts/IAccountManager.aidl
+++ b/core/java/android/accounts/IAccountManager.aidl
@@ -98,4 +98,8 @@
 
     /* Check if an account exists on any user on the device. */
     boolean someUserHasAccount(in Account account);
+
+    /* Check if credentials update is suggested */
+    void isCredentialsUpdateSuggested(in IAccountManagerResponse response, in Account account,
+        String statusToken);
 }
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 2175a9e..2dc4fb9 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -600,6 +600,14 @@
         public static boolean allowTopTaskToReturnHome(int stackId) {
             return stackId != PINNED_STACK_ID;
         }
+
+        /**
+         * Returns true if the stack should be resized to match the bounds specified by
+         * {@link ActivityOptions#setLaunchBounds} when launching an activity into the stack.
+         */
+        public static boolean resizeStackWithLaunchBounds(int stackId) {
+            return stackId == PINNED_STACK_ID;
+        }
     }
 
     /**
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index e163b1c..20eaf0b 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -26,6 +26,7 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -1416,11 +1417,30 @@
      * at this point.  If you want to do work once the activity itself is
      * created, see {@link #onActivityCreated(Bundle)}.
      *
+     * <p>If your app's <code>targetSdkVersion</code> is 23 or lower, child fragments
+     * being restored from the savedInstanceState are restored after <code>onCreate</code>
+     * returns. When targeting N or above and running on an N or newer platform version
+     * they are restored by <code>Fragment.onCreate</code>.</p>
+     *
      * @param savedInstanceState If the fragment is being re-created from
      * a previous saved state, this is the state.
      */
     public void onCreate(@Nullable Bundle savedInstanceState) {
         mCalled = true;
+        final Context context = getContext();
+        final int version = context != null ? context.getApplicationInfo().targetSdkVersion : 0;
+        if (version >= Build.VERSION_CODES.N) {
+            if (savedInstanceState != null) {
+                Parcelable p = savedInstanceState.getParcelable(Activity.FRAGMENTS_TAG);
+                if (p != null) {
+                    if (mChildFragmentManager == null) {
+                        instantiateChildFragmentManager();
+                    }
+                    mChildFragmentManager.restoreAllState(p, null);
+                    mChildFragmentManager.dispatchCreate();
+                }
+            }
+        }
     }
 
     /**
@@ -2210,14 +2230,18 @@
             throw new SuperNotCalledException("Fragment " + this
                     + " did not call through to super.onCreate()");
         }
-        if (savedInstanceState != null) {
-            Parcelable p = savedInstanceState.getParcelable(Activity.FRAGMENTS_TAG);
-            if (p != null) {
-                if (mChildFragmentManager == null) {
-                    instantiateChildFragmentManager();
+        final Context context = getContext();
+        final int version = context != null ? context.getApplicationInfo().targetSdkVersion : 0;
+        if (version < Build.VERSION_CODES.N) {
+            if (savedInstanceState != null) {
+                Parcelable p = savedInstanceState.getParcelable(Activity.FRAGMENTS_TAG);
+                if (p != null) {
+                    if (mChildFragmentManager == null) {
+                        instantiateChildFragmentManager();
+                    }
+                    mChildFragmentManager.restoreAllState(p, null);
+                    mChildFragmentManager.dispatchCreate();
                 }
-                mChildFragmentManager.restoreAllState(p, null);
-                mChildFragmentManager.dispatchCreate();
             }
         }
     }
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index 1c4dcf7..cfd5ca8 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -411,8 +411,7 @@
     /**
      * Called after the user has changed their password, as a result of
      * receiving {@link #ACTION_PASSWORD_CHANGED}.  At this point you
-     * can use {@link DevicePolicyManager#getCurrentFailedPasswordAttempts()
-     * DevicePolicyManager.getCurrentFailedPasswordAttempts()}
+     * can use {@link DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
      * to retrieve the active password characteristics.
      * @param context The running context as per {@link #onReceive}.
      * @param intent The received intent as per {@link #onReceive}.
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index e3d7c3d..20cacff 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1053,6 +1053,18 @@
     public static final int PASSWORD_QUALITY_COMPLEX = 0x60000;
 
     /**
+     * Constant for {@link #setPasswordQuality}: the user is not allowed to
+     * modify password. In case this password quality is set, the password is
+     * managed by a profile owner. The profile owner can set any password,
+     * as if {@link #PASSWORD_QUALITY_UNSPECIFIED} is used. Note
+     * that quality constants are ordered so that higher values are more
+     * restrictive. The value of {@link #PASSWORD_QUALITY_MANAGED} is
+     * the highest.
+     * @hide
+     */
+    public static final int PASSWORD_QUALITY_MANAGED = 0x80000;
+
+    /**
      * Called by an application that is administering the device to set the
      * password restrictions it is imposing.  After setting this, the user
      * will not be able to enter a new password that is not at least as
@@ -3045,6 +3057,7 @@
      *
      * @hide
      */
+    @SystemApi
     public String getDeviceOwnerNameOnAnyUser() {
         if (mService != null) {
             try {
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index 8b79305..193a0b2c 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -17,13 +17,13 @@
 package android.app.backup;
 
 import android.annotation.SystemApi;
-import android.app.backup.RestoreSession;
-import android.app.backup.IBackupManager;
-import android.app.backup.IRestoreSession;
 import android.content.Context;
+import android.os.Handler;
+import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.Log;
+import android.util.Pair;
 
 /**
  * The interface through which an application interacts with the Android backup service to
@@ -59,6 +59,65 @@
 public class BackupManager {
     private static final String TAG = "BackupManager";
 
+    // BackupObserver status codes
+    /**
+     * Indicates that backup succeeded.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int SUCCESS = 0;
+
+    /**
+     * Indicates that backup is either not enabled at all or
+     * backup for the package was rejected by backup service
+     * or backup transport,
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int ERROR_BACKUP_NOT_ALLOWED = -2001;
+
+    /**
+     * The requested app is not installed on the device.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int ERROR_PACKAGE_NOT_FOUND = -2002;
+
+    /**
+     * The transport for some reason was not in a good state and
+     * aborted the entire backup request. This is a transient
+     * failure and should not be retried immediately.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int ERROR_TRANSPORT_ABORTED = BackupTransport.TRANSPORT_ERROR;
+
+    /**
+     * Returned when the transport was unable to process the
+     * backup request for a given package, for example if the
+     * transport hit a transient network failure. The remaining
+     * packages provided to {@link #requestBackup(String[], BackupObserver)}
+     * will still be attempted.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int ERROR_TRANSPORT_PACKAGE_REJECTED =
+            BackupTransport.TRANSPORT_PACKAGE_REJECTED;
+
+    /**
+     * The {@link BackupAgent} for the requested package failed for some reason
+     * and didn't provide appropriate backup data.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int ERROR_AGENT_FAILURE = BackupTransport.AGENT_ERROR;
+
     private Context mContext;
     private static IBackupManager sService;
 
@@ -365,4 +424,94 @@
         }
         return 0;
     }
+
+    /**
+     * Request an immediate backup, providing an observer to which results of the backup operation
+     * will be published. The Android backup system will decide for each package whether it will
+     * be full app data backup or key/value-pair-based backup.
+     *
+     * <p>If this method returns {@link BackupManager#SUCCESS}, the OS will attempt to backup all
+     * provided packages using the remote transport.
+     *
+     * @param packages List of package names to backup.
+     * @param observer The {@link BackupObserver} to receive callbacks during the backup
+     * operation.
+     * @return {@link BackupManager#SUCCESS} on success; nonzero on error.
+     * @exception  IllegalArgumentException on null or empty {@code packages} param.
+     *
+     * @hide
+     */
+    @SystemApi
+    public int requestBackup(String[] packages, BackupObserver observer) {
+        checkServiceBinder();
+        if (sService != null) {
+            try {
+                BackupObserverWrapper observerWrapper =
+                    new BackupObserverWrapper(mContext, observer);
+                return sService.requestBackup(packages, observerWrapper);
+            } catch (RemoteException e) {
+                Log.e(TAG, "requestBackup() couldn't connect");
+            }
+        }
+        return -1;
+    }
+
+    /*
+     * We wrap incoming binder calls with a private class implementation that
+     * redirects them into main-thread actions.  This serializes the backup
+     * progress callbacks nicely within the usual main-thread lifecycle pattern.
+     */
+    @SystemApi
+    private class BackupObserverWrapper extends IBackupObserver.Stub {
+        final Handler mHandler;
+        final BackupObserver mObserver;
+
+        static final int MSG_UPDATE = 1;
+        static final int MSG_RESULT = 2;
+        static final int MSG_FINISHED = 3;
+
+        BackupObserverWrapper(Context context, BackupObserver observer) {
+            mHandler = new Handler(context.getMainLooper()) {
+                @Override
+                public void handleMessage(Message msg) {
+                    switch (msg.what) {
+                        case MSG_UPDATE:
+                            Pair<String, BackupProgress> obj =
+                                (Pair<String, BackupProgress>) msg.obj;
+                            mObserver.onUpdate(obj.first, obj.second);
+                            break;
+                        case MSG_RESULT:
+                            mObserver.onResult((String)msg.obj, msg.arg1);
+                            break;
+                        case MSG_FINISHED:
+                            mObserver.backupFinished(msg.arg1);
+                            break;
+                        default:
+                            Log.w(TAG, "Unknown message: " + msg);
+                            break;
+                    }
+                }
+            };
+            mObserver = observer;
+        }
+
+        // Binder calls into this object just enqueue on the main-thread handler
+        @Override
+        public void onUpdate(String currentPackage, BackupProgress backupProgress) {
+            mHandler.sendMessage(
+                mHandler.obtainMessage(MSG_UPDATE, Pair.create(currentPackage, backupProgress)));
+        }
+
+        @Override
+        public void onResult(String currentPackage, int status) {
+            mHandler.sendMessage(
+                mHandler.obtainMessage(MSG_FINISHED, status, 0, currentPackage));
+        }
+
+        @Override
+        public void backupFinished(int status) {
+            mHandler.sendMessage(
+                mHandler.obtainMessage(MSG_FINISHED, status, 0));
+        }
+    }
 }
diff --git a/core/java/android/app/backup/BackupObserver.java b/core/java/android/app/backup/BackupObserver.java
new file mode 100644
index 0000000..0dd071e
--- /dev/null
+++ b/core/java/android/app/backup/BackupObserver.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.app.backup;
+
+import android.annotation.SystemApi;
+
+/**
+ * Callback class for receiving progress reports during a backup operation.  These
+ * methods will all be called on your application's main thread.
+ *
+ * @hide
+ */
+@SystemApi
+public abstract class BackupObserver {
+    /**
+     * This method could be called several times for packages with full data backup.
+     * It will tell how much of backup data is already saved and how much is expected.
+     *
+     * @param currentBackupPackage The name of the package that now being backuped.
+     * @param backupProgress Current progress of backup for the package.
+     */
+    public void onUpdate(String currentBackupPackage, BackupProgress backupProgress) {
+    }
+
+    /**
+     * The backup of single package has completed.  This method will be called at most one time
+     * for each package and could be not called if backup is failed before and
+     * backupFinished() is called.
+     *
+     * @param currentBackupPackage The name of the package that was backuped.
+     * @param status Zero on success; a nonzero error code if the backup operation failed.
+     */
+    public void onResult(String currentBackupPackage, int status) {
+    }
+
+    /**
+     * The backup process has completed.  This method will always be called,
+     * even if no individual package backup operations were attempted.
+     *
+     * @param status Zero on success; a nonzero error code if the backup operation
+     *   as a whole failed.
+     */
+    public void backupFinished(int status) {
+    }
+}
diff --git a/core/java/android/app/backup/BackupProgress.aidl b/core/java/android/app/backup/BackupProgress.aidl
new file mode 100644
index 0000000..c10b9a2
--- /dev/null
+++ b/core/java/android/app/backup/BackupProgress.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.backup;
+
+parcelable BackupProgress;
\ No newline at end of file
diff --git a/core/java/android/app/backup/BackupProgress.java b/core/java/android/app/backup/BackupProgress.java
new file mode 100644
index 0000000..32e6212
--- /dev/null
+++ b/core/java/android/app/backup/BackupProgress.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.app.backup;
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Information about current progress of full data backup
+ * Used in {@link BackupObserver#onUpdate(String, BackupProgress)}
+ *
+ * @hide
+ */
+@SystemApi
+public class BackupProgress implements Parcelable {
+
+    /**
+     * Expected size of data in full backup.
+     */
+    public final long bytesExpected;
+    /**
+     * Amount of backup data that is already saved in backup.
+     */
+    public final long bytesTransferred;
+
+    public BackupProgress(long _bytesExpected, long _bytesTransferred) {
+        bytesExpected = _bytesExpected;
+        bytesTransferred = _bytesTransferred;
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeLong(bytesExpected);
+        out.writeLong(bytesTransferred);
+    }
+
+    public static final Creator<BackupProgress> CREATOR = new Creator<BackupProgress>() {
+        public BackupProgress createFromParcel(Parcel in) {
+            return new BackupProgress(in);
+        }
+
+        public BackupProgress[] newArray(int size) {
+            return new BackupProgress[size];
+        }
+    };
+
+    private BackupProgress(Parcel in) {
+        bytesExpected = in.readLong();
+        bytesTransferred = in.readLong();
+    }
+}
diff --git a/core/java/android/app/backup/BackupTransport.java b/core/java/android/app/backup/BackupTransport.java
index 954ccef..4363604 100644
--- a/core/java/android/app/backup/BackupTransport.java
+++ b/core/java/android/app/backup/BackupTransport.java
@@ -50,6 +50,10 @@
     public static final int AGENT_ERROR = -1003;
     public static final int AGENT_UNKNOWN = -1004;
 
+    // Indicates that operation was initiated by user, not a scheduled one.
+    // Transport should ignore its own moratoriums for call with this flag set.
+    public static final int FLAG_USER_INITIATED = 1;
+
     IBackupTransport mBinderImpl = new TransportImpl();
 
     public IBinder getBinder() {
@@ -228,13 +232,10 @@
      *
      * @param packageInfo The identity of the application whose data is being backed up.
      *   This specifically includes the signature list for the package.
-     * @param data The data stream that resulted from invoking the application's
+     * @param inFd Descriptor of file with data that resulted from invoking the application's
      *   BackupService.doBackup() method.  This may be a pipe rather than a file on
      *   persistent media, so it may not be seekable.
-     * @param wipeAllFirst When true, <i>all</i> backed-up data for the current device/account
-     *   must be erased prior to the storage of the data provided here.  The purpose of this
-     *   is to provide a guarantee that no stale data exists in the restore set when the
-     *   device begins providing incremental backups.
+     * @param flags {@link BackupTransport#FLAG_USER_INITIATED} or 0.
      * @return one of {@link BackupTransport#TRANSPORT_OK} (OK so far),
      *  {@link BackupTransport#TRANSPORT_PACKAGE_REJECTED} (to suppress backup of this
      *  specific package, but allow others to proceed),
@@ -242,6 +243,14 @@
      *  {@link BackupTransport#TRANSPORT_NOT_INITIALIZED} (if the backend dataset has
      *  become lost due to inactivity purge or some other reason and needs re-initializing)
      */
+    public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd, int flags) {
+        return performBackup(packageInfo, inFd);
+    }
+
+    /**
+     * Legacy version of {@link #performBackup(PackageInfo, ParcelFileDescriptor, int)} that
+     * doesn't use flags parameter.
+     */
     public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd) {
         return BackupTransport.TRANSPORT_ERROR;
     }
@@ -392,11 +401,21 @@
      *    close this file descriptor now; otherwise it should be cached for use during
      *    succeeding calls to {@link #sendBackupData(int)}, and closed in response to
      *    {@link #finishBackup()}.
+     * @param flags {@link BackupTransport#FLAG_USER_INITIATED} or 0.
      * @return TRANSPORT_PACKAGE_REJECTED to indicate that the stated application is not
      *    to be backed up; TRANSPORT_OK to indicate that the OS may proceed with delivering
      *    backup data; TRANSPORT_ERROR to indicate a fatal error condition that precludes
      *    performing a backup at this time.
      */
+    public int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket,
+            int flags) {
+        return performFullBackup(targetPackage, socket);
+    }
+
+    /**
+     * Legacy version of {@link #performFullBackup(PackageInfo, ParcelFileDescriptor, int)} that
+     * doesn't use flags parameter.
+     */
     public int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket) {
         return BackupTransport.TRANSPORT_PACKAGE_REJECTED;
     }
@@ -568,9 +587,9 @@
         }
 
         @Override
-        public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd)
+        public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd, int flags)
                 throws RemoteException {
-            return BackupTransport.this.performBackup(packageInfo, inFd);
+            return BackupTransport.this.performBackup(packageInfo, inFd, flags);
         }
 
         @Override
@@ -619,8 +638,9 @@
         }
 
         @Override
-        public int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket) throws RemoteException {
-            return BackupTransport.this.performFullBackup(targetPackage, socket);
+        public int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket,
+                int flags) throws RemoteException {
+            return BackupTransport.this.performFullBackup(targetPackage, socket, flags);
         }
 
         @Override
diff --git a/core/java/android/app/backup/IBackupManager.aidl b/core/java/android/app/backup/IBackupManager.aidl
index 87e4ef1..2a1c00f 100644
--- a/core/java/android/app/backup/IBackupManager.aidl
+++ b/core/java/android/app/backup/IBackupManager.aidl
@@ -16,6 +16,7 @@
 
 package android.app.backup;
 
+import android.app.backup.IBackupObserver;
 import android.app.backup.IFullBackupRestoreObserver;
 import android.app.backup.IRestoreSession;
 import android.os.ParcelFileDescriptor;
@@ -326,4 +327,19 @@
      *     no suitable data is available.
      */
     long getAvailableRestoreToken(String packageName);
+
+    /**
+     * Request an immediate backup, providing an observer to which results of the backup operation
+     * will be published. The Android backup system will decide for each package whether it will
+     * be full app data backup or key/value-pair-based backup.
+     *
+     * <p>If this method returns zero (meaning success), the OS will attempt to backup all provided
+     * packages using the remote transport.
+     *
+     * @param observer The {@link BackupObserver} to receive callbacks during the backup
+     * operation.
+     *
+     * @return Zero on success; nonzero on error.
+     */
+    int requestBackup(in String[] packages, IBackupObserver observer);
 }
diff --git a/core/java/android/app/backup/IBackupObserver.aidl b/core/java/android/app/backup/IBackupObserver.aidl
new file mode 100644
index 0000000..821a589
--- /dev/null
+++ b/core/java/android/app/backup/IBackupObserver.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.backup;
+
+import android.app.backup.BackupProgress;
+
+/**
+ * Callback class for receiving progress reports during a backup operation.  These
+ * methods will all be called on your application's main thread.
+ *
+ * @hide
+ */
+oneway interface IBackupObserver {
+    /**
+     * This method could be called several times for packages with full data backup.
+     * It will tell how much of backup data is already saved and how much is expected.
+     *
+     * @param currentBackupPackage The name of the package that now being backuped.
+     * @param backupProgress Current progress of backup for the package.
+     */
+    void onUpdate(String currentPackage, in BackupProgress backupProgress);
+
+    /**
+     * The backup of single package has completed.  This method will be called at most one time
+     * for each package and could be not called if backup is failed before and
+     * backupFinished() is called.
+     *
+     * @param currentBackupPackage The name of the package that was backuped.
+     * @param status Zero on success; a nonzero error code if the backup operation failed.
+     */
+    void onResult(String currentPackage, int status);
+
+    /**
+     * The backup process has completed.  This method will always be called,
+     * even if no individual package backup operations were attempted.
+     *
+     * @param status Zero on success; a nonzero error code if the backup operation
+     *   as a whole failed.
+     */
+    void backupFinished(int status);
+}
diff --git a/core/java/android/app/backup/RestoreSet.java b/core/java/android/app/backup/RestoreSet.java
index aacaf7c..4a6316c 100644
--- a/core/java/android/app/backup/RestoreSet.java
+++ b/core/java/android/app/backup/RestoreSet.java
@@ -58,7 +58,6 @@
         token = _token;
     }
 
-
     // Parcelable implementation
     public int describeContents() {
         return 0;
diff --git a/core/java/android/app/usage/NetworkStats.java b/core/java/android/app/usage/NetworkStats.java
index 5f97c9e..d263646 100644
--- a/core/java/android/app/usage/NetworkStats.java
+++ b/core/java/android/app/usage/NetworkStats.java
@@ -208,6 +208,15 @@
             return uid;
         }
 
+        private static int convertRoaming(int roaming) {
+            switch (roaming) {
+                case android.net.NetworkStats.ROAMING_ALL : return ROAMING_ALL;
+                case android.net.NetworkStats.ROAMING_DEFAULT : return ROAMING_DEFAULT;
+                case android.net.NetworkStats.ROAMING_ROAMING : return ROAMING_ROAMING;
+            }
+            return 0;
+        }
+
         public Bucket() {
         }
 
@@ -454,9 +463,9 @@
     private void fillBucketFromSummaryEntry(Bucket bucketOut) {
         bucketOut.mUid = Bucket.convertUid(mRecycledSummaryEntry.uid);
         bucketOut.mState = Bucket.convertState(mRecycledSummaryEntry.set);
-        // TODO: Implement metering/roaming tracking.
+        // TODO: Implement metering tracking.
         bucketOut.mMetering = Bucket.METERING_ALL;
-        bucketOut.mRoaming = Bucket.ROAMING_ALL;
+        bucketOut.mRoaming = Bucket.convertRoaming(mRecycledSummaryEntry.roaming);
         bucketOut.mBeginTimeStamp = mStartTimeStamp;
         bucketOut.mEndTimeStamp = mEndTimeStamp;
         bucketOut.mRxBytes = mRecycledSummaryEntry.rxBytes;
diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java
index 0fce7a9..e8373a1 100644
--- a/core/java/android/app/usage/NetworkStatsManager.java
+++ b/core/java/android/app/usage/NetworkStatsManager.java
@@ -40,16 +40,17 @@
  * {@link #querySummaryForUser} <p />
  * {@link #querySummary} <p />
  * These queries aggregate network usage across the whole interval. Therefore there will be only one
- * bucket for a particular key and state combination. In case of the user-wide and device-wide
- * summaries a single bucket containing the totalised network usage is returned.
+ * bucket for a particular key and state and roaming combination. In case of the user-wide and
+ * device-wide summaries a single bucket containing the totalised network usage is returned.
  * <h3>
  * History queries
  * </h3>
  * {@link #queryDetailsForUid} <p />
  * {@link #queryDetails} <p />
- * These queries do not aggregate over time but do aggregate over state. Therefore there can be
- * multiple buckets for a particular key but all Bucket's state is going to be
- * {@link NetworkStats.Bucket#STATE_ALL}.
+ * These queries do not aggregate over time but do aggregate over state and roaming. Therefore there
+ * can be multiple buckets for a particular key but all Bucket's state is going to be
+ * {@link NetworkStats.Bucket#STATE_ALL} and all Bucket's roaming is going to be
+ * {@link NetworkStats.Bucket#ROAMING_ALL}.
  * <p />
  * <b>NOTE:</b> Accessing stats for apps other than the calling app requires the permission
  * {@link android.Manifest.permission#PACKAGE_USAGE_STATS}, which is a system-level permission and
@@ -81,8 +82,8 @@
      * Query network usage statistics summaries. Result is summarised data usage for the whole
      * device. Result is a single Bucket aggregated over time, state and uid. This means the
      * bucket's start and end timestamp are going to be the same as the 'startTime' and 'endTime'
-     * parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid
-     * {@link NetworkStats.Bucket#UID_ALL}.
+     * parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL}, uid
+     * {@link NetworkStats.Bucket#UID_ALL}, and roaming {@link NetworkStats.Bucket#ROAMING_ALL}.
      *
      * @param networkType As defined in {@link ConnectivityManager}, e.g.
      *            {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
@@ -114,8 +115,8 @@
      * Query network usage statistics summaries. Result is summarised data usage for all uids
      * belonging to calling user. Result is a single Bucket aggregated over time, state and uid.
      * This means the bucket's start and end timestamp are going to be the same as the 'startTime'
-     * and 'endTime' parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid
-     * {@link NetworkStats.Bucket#UID_ALL}.
+     * and 'endTime' parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL}, uid
+     * {@link NetworkStats.Bucket#UID_ALL}, and roaming {@link NetworkStats.Bucket#ROAMING_ALL}.
      *
      * @param networkType As defined in {@link ConnectivityManager}, e.g.
      *            {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
@@ -146,7 +147,7 @@
     /**
      * Query network usage statistics summaries. Result filtered to include only uids belonging to
      * calling user. Result is aggregated over time, hence all buckets will have the same start and
-     * end timestamps. Not aggregated over state or uid. This means buckets' start and end
+     * end timestamps. Not aggregated over state, uid, or roaming. This means buckets' start and end
      * timestamps are going to be the same as the 'startTime' and 'endTime' parameters, state and
      * uid are going to vary.
      *
@@ -179,7 +180,8 @@
      * Query network usage statistics details. Only usable for uids belonging to calling user.
      * Result is aggregated over state but not aggregated over time. This means buckets' start and
      * end timestamps are going to be between 'startTime' and 'endTime' parameters, state is going
-     * to be {@link NetworkStats.Bucket#STATE_ALL} and uid the same as the 'uid' parameter.
+     * to be {@link NetworkStats.Bucket#STATE_ALL} and uid the same as the 'uid' parameter. roaming
+     * is going to be {@link NetworkStats.Bucket#ROAMING_ALL}.
      * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't
      * interpolate across partial buckets. Since bucket length is in the order of hours, this
      * method cannot be used to measure data usage on a fine grained time scale.
@@ -215,6 +217,7 @@
      * calling user. Result is aggregated over state but not aggregated over time or uid. This means
      * buckets' start and end timestamps are going to be between 'startTime' and 'endTime'
      * parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid will vary.
+     * roaming is going to be {@link NetworkStats.Bucket#ROAMING_ALL}.
      * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't
      * interpolate across partial buckets. Since bucket length is in the order of hours, this
      * method cannot be used to measure data usage on a fine grained time scale.
diff --git a/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java b/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java
index 834a587..e32a470 100644
--- a/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java
+++ b/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java
@@ -19,6 +19,8 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.util.Arrays;
+
 /**
  * Record of energy and activity information from controller and
  * underlying bt stack state.Timestamp the record with system
@@ -27,11 +29,12 @@
  */
 public final class BluetoothActivityEnergyInfo implements Parcelable {
     private final long mTimestamp;
-    private final int mBluetoothStackState;
-    private final long mControllerTxTimeMs;
-    private final long mControllerRxTimeMs;
-    private final long mControllerIdleTimeMs;
-    private final long mControllerEnergyUsed;
+    private int mBluetoothStackState;
+    private long mControllerTxTimeMs;
+    private long mControllerRxTimeMs;
+    private long mControllerIdleTimeMs;
+    private long mControllerEnergyUsed;
+    private UidTraffic[] mUidTraffic;
 
     public static final int BT_STACK_STATE_INVALID = 0;
     public static final int BT_STACK_STATE_STATE_ACTIVE = 1;
@@ -48,6 +51,17 @@
         mControllerEnergyUsed = energyUsed;
     }
 
+    @SuppressWarnings("unchecked")
+    BluetoothActivityEnergyInfo(Parcel in) {
+        mTimestamp = in.readLong();
+        mBluetoothStackState = in.readInt();
+        mControllerTxTimeMs = in.readLong();
+        mControllerRxTimeMs = in.readLong();
+        mControllerIdleTimeMs = in.readLong();
+        mControllerEnergyUsed = in.readLong();
+        mUidTraffic = in.createTypedArray(UidTraffic.CREATOR);
+    }
+
     @Override
     public String toString() {
         return "BluetoothActivityEnergyInfo{"
@@ -57,26 +71,22 @@
             + " mControllerRxTimeMs=" + mControllerRxTimeMs
             + " mControllerIdleTimeMs=" + mControllerIdleTimeMs
             + " mControllerEnergyUsed=" + mControllerEnergyUsed
+            + " mUidTraffic=" + Arrays.toString(mUidTraffic)
             + " }";
     }
 
     public static final Parcelable.Creator<BluetoothActivityEnergyInfo> CREATOR =
             new Parcelable.Creator<BluetoothActivityEnergyInfo>() {
         public BluetoothActivityEnergyInfo createFromParcel(Parcel in) {
-            long timestamp = in.readLong();
-            int stackState = in.readInt();
-            long txTime = in.readLong();
-            long rxTime = in.readLong();
-            long idleTime = in.readLong();
-            long energyUsed = in.readLong();
-            return new BluetoothActivityEnergyInfo(timestamp, stackState,
-                    txTime, rxTime, idleTime, energyUsed);
+            return new BluetoothActivityEnergyInfo(in);
         }
+
         public BluetoothActivityEnergyInfo[] newArray(int size) {
             return new BluetoothActivityEnergyInfo[size];
         }
     };
 
+    @SuppressWarnings("unchecked")
     public void writeToParcel(Parcel out, int flags) {
         out.writeLong(mTimestamp);
         out.writeInt(mBluetoothStackState);
@@ -84,6 +94,7 @@
         out.writeLong(mControllerRxTimeMs);
         out.writeLong(mControllerIdleTimeMs);
         out.writeLong(mControllerEnergyUsed);
+        out.writeTypedArray(mUidTraffic, flags);
     }
 
     public int describeContents() {
@@ -133,6 +144,14 @@
         return mTimestamp;
     }
 
+    public UidTraffic[] getUidTraffic() {
+        return mUidTraffic;
+    }
+
+    public void setUidTraffic(UidTraffic[] traffic) {
+        mUidTraffic = traffic;
+    }
+
     /**
      * @return if the record is valid
      */
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClientCall.java b/core/java/android/bluetooth/BluetoothHeadsetClientCall.java
index 002f63f..c73bc3c 100644
--- a/core/java/android/bluetooth/BluetoothHeadsetClientCall.java
+++ b/core/java/android/bluetooth/BluetoothHeadsetClientCall.java
@@ -196,7 +196,7 @@
 
     public String toString(boolean loggable) {
         StringBuilder builder = new StringBuilder("BluetoothHeadsetClientCall{mDevice: ");
-        builder.append(loggable ? mDevice.hashCode() : mDevice);
+        builder.append(loggable ? mDevice : mDevice.hashCode());
         builder.append(", mId: ");
         builder.append(mId);
         builder.append(", mUUID: ");
@@ -214,7 +214,7 @@
             default: builder.append(mState); break;
         }
         builder.append(", mNumber: ");
-        builder.append(loggable ? mNumber.hashCode() : mNumber);
+        builder.append(loggable ? mNumber : mNumber.hashCode());
         builder.append(", mMultiParty: ");
         builder.append(mMultiParty);
         builder.append(", mOutgoing: ");
diff --git a/core/java/android/bluetooth/UidTraffic.java b/core/java/android/bluetooth/UidTraffic.java
new file mode 100644
index 0000000..78013cc
--- /dev/null
+++ b/core/java/android/bluetooth/UidTraffic.java
@@ -0,0 +1,111 @@
+/*
+ * 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.bluetooth;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Record of data traffic (in bytes) by an application identified by its UID.
+ * @hide
+ */
+public class UidTraffic implements Cloneable, Parcelable {
+    private final int mAppUid;
+    private long mRxBytes;
+    private long mTxBytes;
+
+    public UidTraffic(int appUid) {
+        mAppUid = appUid;
+    }
+
+    public UidTraffic(int appUid, long rx, long tx) {
+        mAppUid = appUid;
+        mRxBytes = rx;
+        mTxBytes = tx;
+    }
+
+    UidTraffic(Parcel in) {
+        mAppUid = in.readInt();
+        mRxBytes = in.readLong();
+        mTxBytes = in.readLong();
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mAppUid);
+        dest.writeLong(mRxBytes);
+        dest.writeLong(mTxBytes);
+    }
+
+    public void setRxBytes(long bytes) {
+        mRxBytes = bytes;
+    }
+
+    public void setTxBytes(long bytes) {
+        mTxBytes = bytes;
+    }
+
+    public void addRxBytes(long bytes) {
+        mRxBytes += bytes;
+    }
+
+    public void addTxBytes(long bytes) {
+        mTxBytes += bytes;
+    }
+
+    public int getUid() {
+        return mAppUid;
+    }
+
+    public long getRxBytes() {
+        return mRxBytes;
+    }
+
+    public long getTxBytes() {
+        return mTxBytes;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public UidTraffic clone() {
+        return new UidTraffic(mAppUid, mRxBytes, mTxBytes);
+    }
+
+    @Override
+    public String toString() {
+        return "UidTraffic{" +
+                "mAppUid=" + mAppUid +
+                ", mRxBytes=" + mRxBytes +
+                ", mTxBytes=" + mTxBytes +
+                '}';
+    }
+
+    public static final Creator<UidTraffic> CREATOR = new Creator<UidTraffic>() {
+        @Override
+        public UidTraffic createFromParcel(Parcel source) {
+            return new UidTraffic(source);
+        }
+
+        @Override
+        public UidTraffic[] newArray(int size) {
+            return new UidTraffic[size];
+        }
+    };
+}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index c627436..1e7512d 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -541,6 +541,8 @@
  *     <li> {@link #ACTION_PACKAGE_REMOVED}
  *     <li> {@link #ACTION_PACKAGE_RESTARTED}
  *     <li> {@link #ACTION_PACKAGE_DATA_CLEARED}
+ *     <li> {@link #ACTION_PACKAGES_SUSPENDED}
+ *     <li> {@link #ACTION_PACKAGES_UNSUSPENDED}
  *     <li> {@link #ACTION_UID_REMOVED}
  *     <li> {@link #ACTION_BATTERY_CHANGED}
  *     <li> {@link #ACTION_POWER_CONNECTED}
@@ -2118,6 +2120,30 @@
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_PACKAGE_DATA_CLEARED = "android.intent.action.PACKAGE_DATA_CLEARED";
     /**
+     * Broadcast Action: Packages have been suspended.
+     * <p>Includes the following extras:
+     * <ul>
+     * <li> {@link #EXTRA_CHANGED_PACKAGE_LIST} is the set of packages which have been suspended
+     * </ul>
+     *
+     * <p class="note">This is a protected intent that can only be sent
+     * by the system. It is only sent to registered receivers.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_PACKAGES_SUSPENDED = "android.intent.action.PACKAGES_SUSPENDED";
+    /**
+     * Broadcast Action: Packages have been unsuspended.
+     * <p>Includes the following extras:
+     * <ul>
+     * <li> {@link #EXTRA_CHANGED_PACKAGE_LIST} is the set of packages which have been unsuspended
+     * </ul>
+     *
+     * <p class="note">This is a protected intent that can only be sent
+     * by the system. It is only sent to registered receivers.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_PACKAGES_UNSUSPENDED = "android.intent.action.PACKAGES_UNSUSPENDED";
+    /**
      * Broadcast Action: A user ID has been removed from the system.  The user
      * ID number is stored in the extra data under {@link #EXTRA_UID}.
      *
@@ -3950,7 +3976,9 @@
     /**
      * This field is part of
      * {@link android.content.Intent#ACTION_EXTERNAL_APPLICATIONS_AVAILABLE},
-     * {@link android.content.Intent#ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE}
+     * {@link android.content.Intent#ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE},
+     * {@link android.content.Intent#ACTION_PACKAGES_SUSPENDED},
+     * {@link android.content.Intent#ACTION_PACKAGES_UNSUSPENDED}
      * and contains a string array of all of the components that have changed.
      */
     public static final String EXTRA_CHANGED_PACKAGE_LIST =
diff --git a/core/java/android/content/SyncInfo.java b/core/java/android/content/SyncInfo.java
index a586d6f..ab3c30b 100644
--- a/core/java/android/content/SyncInfo.java
+++ b/core/java/android/content/SyncInfo.java
@@ -24,6 +24,13 @@
  * Information about the sync operation that is currently underway.
  */
 public class SyncInfo implements Parcelable {
+    /**
+     * Used when the caller receiving this object doesn't have permission to access the accounts
+     * on device.
+     * @See Manifest.permission.GET_ACCOUNTS
+     */
+    private static final Account REDACTED_ACCOUNT = new Account("*****", "*****");
+
     /** @hide */
     public final int authorityId;
 
@@ -44,6 +51,17 @@
      */
     public final long startTime;
 
+    /**
+     * Creates a SyncInfo object with an unusable Account. Used when the caller receiving this
+     * object doesn't have access to the accounts on the device.
+     * @See Manifest.permission.GET_ACCOUNTS
+     * @hide
+     */
+    public static SyncInfo createAccountRedacted(
+        int authorityId, String authority, long startTime) {
+            return new SyncInfo(authorityId, REDACTED_ACCOUNT, authority, startTime);
+    }
+
     /** @hide */
     public SyncInfo(int authorityId, Account account, String authority, long startTime) {
         this.authorityId = authorityId;
diff --git a/core/java/android/content/pm/ILauncherApps.aidl b/core/java/android/content/pm/ILauncherApps.aidl
index 6586426..cc266c5 100644
--- a/core/java/android/content/pm/ILauncherApps.aidl
+++ b/core/java/android/content/pm/ILauncherApps.aidl
@@ -18,6 +18,7 @@
 
 import android.content.ComponentName;
 import android.content.Intent;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.IOnAppsChangedListener;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.ResolveInfo;
@@ -40,4 +41,5 @@
             in Bundle opts, in UserHandle user);
     boolean isPackageEnabled(String packageName, in UserHandle user);
     boolean isActivityEnabled(in ComponentName component, in UserHandle user);
+    ApplicationInfo getApplicationInfo(String packageName, int flags, in UserHandle user);
 }
diff --git a/core/java/android/content/pm/IOnAppsChangedListener.aidl b/core/java/android/content/pm/IOnAppsChangedListener.aidl
index 796b58d..1303696 100644
--- a/core/java/android/content/pm/IOnAppsChangedListener.aidl
+++ b/core/java/android/content/pm/IOnAppsChangedListener.aidl
@@ -27,4 +27,6 @@
     void onPackageChanged(in UserHandle user, String packageName);
     void onPackagesAvailable(in UserHandle user, in String[] packageNames, boolean replacing);
     void onPackagesUnavailable(in UserHandle user, in String[] packageNames, boolean replacing);
+    void onPackagesSuspended(in UserHandle user, in String[] packageNames);
+    void onPackagesUnsuspended(in UserHandle user, in String[] packageNames);
 }
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 90a1198..2c6b604 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -429,6 +429,12 @@
     void performFstrimIfNeeded();
 
     /**
+     * Ask the package manager to extract packages if needed, to save
+     * the VM unzipping the APK in memory during launch.
+     */
+    void extractPackagesIfNeeded();
+
+    /**
      * Notify the package manager that a package is going to be used.
      */
     void notifyPackageUse(String packageName);
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 6e67af4..8c7d327 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -21,6 +21,7 @@
 import android.content.Intent;
 import android.content.pm.ILauncherApps;
 import android.content.pm.IOnAppsChangedListener;
+import android.content.pm.PackageManager.ApplicationInfoFlags;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.graphics.Rect;
 import android.os.Bundle;
@@ -123,6 +124,30 @@
          */
         abstract public void onPackagesUnavailable(String[] packageNames, UserHandle user,
                 boolean replacing);
+
+        /**
+         * Indicates that one or more packages have been suspended. For
+         * example, this can happen when a Device Administrator suspends
+         * an applicaton.
+         *
+         * @param packageNames The names of the packages that have just been
+         *            suspended.
+         * @param user The UserHandle of the profile that generated the change.
+         */
+        public void onPackagesSuspended(String[] packageNames, UserHandle user) {
+        }
+
+        /**
+         * Indicates that one or more packages have been unsuspended. For
+         * example, this can happen when a Device Administrator unsuspends
+         * an applicaton.
+         *
+         * @param packageNames The names of the packages that have just been
+         *            unsuspended.
+         * @param user The UserHandle of the profile that generated the change.
+         */
+        public void onPackagesUnsuspended(String[] packageNames, UserHandle user) {
+        }
     }
 
     /** @hide */
@@ -243,6 +268,25 @@
     }
 
     /**
+     * Retrieve all of the information we know about a particular package / application.
+     *
+     * @param packageName The package of the application
+     * @param flags Additional option flags {@link PackageManager#getApplicationInfo}
+     * @param user The UserHandle of the profile.
+     *
+     * @return An {@link ApplicationInfo} containing information about the package or
+     *         null of the package isn't found.
+     */
+    public ApplicationInfo getApplicationInfo(String packageName, @ApplicationInfoFlags int flags,
+            UserHandle user) {
+        try {
+            return mService.getApplicationInfo(packageName, flags, user);
+        } catch (RemoteException re) {
+            throw new RuntimeException("Failed to call LauncherAppsService", re);
+        }
+    }
+
+    /**
      * Checks if the activity exists and it enabled for a profile.
      *
      * @param component The activity to check.
@@ -400,7 +444,33 @@
                 for (CallbackMessageHandler callback : mCallbacks) {
                     callback.postOnPackagesUnavailable(packageNames, user, replacing);
                 }
-           }
+            }
+        }
+
+        @Override
+        public void onPackagesSuspended(UserHandle user, String[] packageNames)
+                throws RemoteException {
+            if (DEBUG) {
+                Log.d(TAG, "onPackagesSuspended " + user.getIdentifier() + "," + packageNames);
+            }
+            synchronized (LauncherApps.this) {
+                for (CallbackMessageHandler callback : mCallbacks) {
+                    callback.postOnPackagesSuspended(packageNames, user);
+                }
+            }
+        }
+
+        @Override
+        public void onPackagesUnsuspended(UserHandle user, String[] packageNames)
+                throws RemoteException {
+            if (DEBUG) {
+                Log.d(TAG, "onPackagesUnsuspended " + user.getIdentifier() + "," + packageNames);
+            }
+            synchronized (LauncherApps.this) {
+                for (CallbackMessageHandler callback : mCallbacks) {
+                    callback.postOnPackagesUnsuspended(packageNames, user);
+                }
+            }
         }
     };
 
@@ -410,6 +480,8 @@
         private static final int MSG_CHANGED = 3;
         private static final int MSG_AVAILABLE = 4;
         private static final int MSG_UNAVAILABLE = 5;
+        private static final int MSG_SUSPENDED = 6;
+        private static final int MSG_UNSUSPENDED = 7;
 
         private LauncherApps.Callback mCallback;
 
@@ -447,6 +519,12 @@
                 case MSG_UNAVAILABLE:
                     mCallback.onPackagesUnavailable(info.packageNames, info.user, info.replacing);
                     break;
+                case MSG_SUSPENDED:
+                    mCallback.onPackagesSuspended(info.packageNames, info.user);
+                    break;
+                case MSG_UNSUSPENDED:
+                    mCallback.onPackagesUnsuspended(info.packageNames, info.user);
+                    break;
             }
         }
 
@@ -488,5 +566,19 @@
             info.user = user;
             obtainMessage(MSG_UNAVAILABLE, info).sendToTarget();
         }
+
+        public void postOnPackagesSuspended(String[] packageNames, UserHandle user) {
+            CallbackInfo info = new CallbackInfo();
+            info.packageNames = packageNames;
+            info.user = user;
+            obtainMessage(MSG_SUSPENDED, info).sendToTarget();
+        }
+
+        public void postOnPackagesUnsuspended(String[] packageNames, UserHandle user) {
+            CallbackInfo info = new CallbackInfo();
+            info.packageNames = packageNames;
+            info.user = user;
+            obtainMessage(MSG_UNSUSPENDED, info).sendToTarget();
+        }
     }
 }
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 7b56eeb..ed64ead 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -161,7 +161,11 @@
     final DisplayMetrics mMetrics = new DisplayMetrics();
 
     private final Configuration mConfiguration = new Configuration();
+
+    // Invariant: mResolvedLocale is the resolved locale of mLocalesForResolved
+    private LocaleList mLocalesForResolved = null;
     private Locale mResolvedLocale = null;
+
     private PluralRules mPluralRule;
 
     private CompatibilityInfo mCompatibilityInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
@@ -1950,8 +1954,7 @@
             final int configChanges = calcConfigChanges(config);
 
             LocaleList locales = mConfiguration.getLocales();
-            final boolean setLocalesToDefault = locales.isEmpty();
-            if (setLocalesToDefault) {
+            if (locales.isEmpty()) {
                 locales = LocaleList.getDefault();
                 mConfiguration.setLocales(locales);
             }
@@ -1980,8 +1983,7 @@
                 keyboardHidden = mConfiguration.keyboardHidden;
             }
 
-            if (setLocalesToDefault || mResolvedLocale == null
-                    || (configChanges & Configuration.NATIVE_CONFIG_LOCALE) != 0) {
+            if (locales != mLocalesForResolved) {
                 if (locales.size() == 1) {
                     // This is an optimization to avoid the JNI call(s) when the result of
                     // getFirstMatchWithEnglishSupported() does not depend on the supported locales.
@@ -1997,6 +1999,7 @@
                     }
                     mResolvedLocale = locales.getFirstMatchWithEnglishSupported(supportedLocales);
                 }
+                mLocalesForResolved = locales;
             }
             mAssets.setConfiguration(mConfiguration.mcc, mConfiguration.mnc,
                     adjustLanguageTag(mResolvedLocale.toLanguageTag()),
diff --git a/core/java/android/net/INetworkPolicyManager.aidl b/core/java/android/net/INetworkPolicyManager.aidl
index 7f5f377..06aa616 100644
--- a/core/java/android/net/INetworkPolicyManager.aidl
+++ b/core/java/android/net/INetworkPolicyManager.aidl
@@ -52,6 +52,11 @@
     void setRestrictBackground(boolean restrictBackground);
     boolean getRestrictBackground();
 
+    /** Control which applications can be exempt from background data restrictions */
+    void addRestrictBackgroundWhitelistedUid(int uid);
+    void removeRestrictBackgroundWhitelistedUid(int uid);
+    int[] getRestrictBackgroundWhitelistedUids();
+
     void setDeviceIdleMode(boolean enabled);
 
     NetworkQuotaInfo getNetworkQuotaInfo(in NetworkState state);
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index 77d7e0c..8919d51 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -50,7 +50,7 @@
     public static final int UID_ALL = -1;
     /** {@link #tag} value matching any tag. */
     public static final int TAG_ALL = -1;
-    /** {@link #set} value when all sets combined, not including debug sets. */
+    /** {@link #set} value for all sets combined, not including debug sets. */
     public static final int SET_ALL = -1;
     /** {@link #set} value where background data is accounted. */
     public static final int SET_DEFAULT = 0;
@@ -66,6 +66,13 @@
     /** {@link #tag} value for total data across all tags. */
     public static final int TAG_NONE = 0;
 
+    /** {@link #set} value for all roaming values. */
+    public static final int ROAMING_ALL = -1;
+    /** {@link #set} value where native, non-roaming data is accounted. */
+    public static final int ROAMING_DEFAULT = 0;
+    /** {@link #set} value where roaming data is accounted. */
+    public static final int ROAMING_ROAMING = 1;
+
     // TODO: move fields to "mVariable" notation
 
     /**
@@ -79,6 +86,7 @@
     private int[] uid;
     private int[] set;
     private int[] tag;
+    private int[] roaming;
     private long[] rxBytes;
     private long[] rxPackets;
     private long[] txBytes;
@@ -90,6 +98,12 @@
         public int uid;
         public int set;
         public int tag;
+        /**
+         * Note that this is only populated w/ the default value when read from /proc or written
+         * to disk. We merge in the correct value when reporting this value to clients of
+         * getSummary().
+         */
+        public int roaming;
         public long rxBytes;
         public long rxPackets;
         public long txBytes;
@@ -107,10 +121,17 @@
 
         public Entry(String iface, int uid, int set, int tag, long rxBytes, long rxPackets,
                 long txBytes, long txPackets, long operations) {
+            this(iface, uid, set, tag, ROAMING_DEFAULT, rxBytes, rxPackets, txBytes, txPackets,
+                    operations);
+        }
+
+        public Entry(String iface, int uid, int set, int tag, int roaming, long rxBytes,
+                long rxPackets, long txBytes, long txPackets, long operations) {
             this.iface = iface;
             this.uid = uid;
             this.set = set;
             this.tag = tag;
+            this.roaming = roaming;
             this.rxBytes = rxBytes;
             this.rxPackets = rxPackets;
             this.txBytes = txBytes;
@@ -142,6 +163,7 @@
             builder.append(" uid=").append(uid);
             builder.append(" set=").append(setToString(set));
             builder.append(" tag=").append(tagToString(tag));
+            builder.append(" roaming=").append(roamingToString(roaming));
             builder.append(" rxBytes=").append(rxBytes);
             builder.append(" rxPackets=").append(rxPackets);
             builder.append(" txBytes=").append(txBytes);
@@ -154,8 +176,8 @@
         public boolean equals(Object o) {
             if (o instanceof Entry) {
                 final Entry e = (Entry) o;
-                return uid == e.uid && set == e.set && tag == e.tag && rxBytes == e.rxBytes
-                        && rxPackets == e.rxPackets && txBytes == e.txBytes
+                return uid == e.uid && set == e.set && tag == e.tag && roaming == e.roaming
+                        && rxBytes == e.rxBytes && rxPackets == e.rxPackets && txBytes == e.txBytes
                         && txPackets == e.txPackets && operations == e.operations
                         && iface.equals(e.iface);
             }
@@ -172,6 +194,7 @@
             this.uid = new int[initialSize];
             this.set = new int[initialSize];
             this.tag = new int[initialSize];
+            this.roaming = new int[initialSize];
             this.rxBytes = new long[initialSize];
             this.rxPackets = new long[initialSize];
             this.txBytes = new long[initialSize];
@@ -184,6 +207,7 @@
             this.uid = EmptyArray.INT;
             this.set = EmptyArray.INT;
             this.tag = EmptyArray.INT;
+            this.roaming = EmptyArray.INT;
             this.rxBytes = EmptyArray.LONG;
             this.rxPackets = EmptyArray.LONG;
             this.txBytes = EmptyArray.LONG;
@@ -200,6 +224,7 @@
         uid = parcel.createIntArray();
         set = parcel.createIntArray();
         tag = parcel.createIntArray();
+        roaming = parcel.createIntArray();
         rxBytes = parcel.createLongArray();
         rxPackets = parcel.createLongArray();
         txBytes = parcel.createLongArray();
@@ -216,6 +241,7 @@
         dest.writeIntArray(uid);
         dest.writeIntArray(set);
         dest.writeIntArray(tag);
+        dest.writeIntArray(roaming);
         dest.writeLongArray(rxBytes);
         dest.writeLongArray(rxPackets);
         dest.writeLongArray(txBytes);
@@ -248,6 +274,13 @@
                 iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations));
     }
 
+    @VisibleForTesting
+    public NetworkStats addValues(String iface, int uid, int set, int tag, int roaming,
+            long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
+        return addValues(new Entry(
+                iface, uid, set, tag, roaming, rxBytes, rxPackets, txBytes, txPackets, operations));
+    }
+
     /**
      * Add new stats entry, copying from given {@link Entry}. The {@link Entry}
      * object can be recycled across multiple calls.
@@ -259,6 +292,7 @@
             uid = Arrays.copyOf(uid, newLength);
             set = Arrays.copyOf(set, newLength);
             tag = Arrays.copyOf(tag, newLength);
+            roaming = Arrays.copyOf(roaming, newLength);
             rxBytes = Arrays.copyOf(rxBytes, newLength);
             rxPackets = Arrays.copyOf(rxPackets, newLength);
             txBytes = Arrays.copyOf(txBytes, newLength);
@@ -271,6 +305,7 @@
         uid[size] = entry.uid;
         set[size] = entry.set;
         tag[size] = entry.tag;
+        roaming[size] = entry.roaming;
         rxBytes[size] = entry.rxBytes;
         rxPackets[size] = entry.rxPackets;
         txBytes[size] = entry.txBytes;
@@ -290,6 +325,7 @@
         entry.uid = uid[i];
         entry.set = set[i];
         entry.tag = tag[i];
+        entry.roaming = roaming[i];
         entry.rxBytes = rxBytes[i];
         entry.rxPackets = rxPackets[i];
         entry.txBytes = txBytes[i];
@@ -327,22 +363,23 @@
     public NetworkStats combineValues(String iface, int uid, int tag, long rxBytes, long rxPackets,
             long txBytes, long txPackets, long operations) {
         return combineValues(
-                iface, uid, SET_DEFAULT, tag, rxBytes, rxPackets, txBytes, txPackets, operations);
+                iface, uid, SET_DEFAULT, tag, rxBytes, rxPackets, txBytes,
+                txPackets, operations);
     }
 
-    public NetworkStats combineValues(String iface, int uid, int set, int tag, long rxBytes,
-            long rxPackets, long txBytes, long txPackets, long operations) {
+    public NetworkStats combineValues(String iface, int uid, int set, int tag,
+            long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
         return combineValues(new Entry(
                 iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations));
     }
 
     /**
      * Combine given values with an existing row, or create a new row if
-     * {@link #findIndex(String, int, int, int)} is unable to find match. Can
+     * {@link #findIndex(String, int, int, int, int)} is unable to find match. Can
      * also be used to subtract values from existing rows.
      */
     public NetworkStats combineValues(Entry entry) {
-        final int i = findIndex(entry.iface, entry.uid, entry.set, entry.tag);
+        final int i = findIndex(entry.iface, entry.uid, entry.set, entry.tag, entry.roaming);
         if (i == -1) {
             // only create new entry when positive contribution
             addValues(entry);
@@ -370,10 +407,10 @@
     /**
      * Find first stats index that matches the requested parameters.
      */
-    public int findIndex(String iface, int uid, int set, int tag) {
+    public int findIndex(String iface, int uid, int set, int tag, int roaming) {
         for (int i = 0; i < size; i++) {
             if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i]
-                    && Objects.equals(iface, this.iface[i])) {
+                    && roaming == this.roaming[i] && Objects.equals(iface, this.iface[i])) {
                 return i;
             }
         }
@@ -385,7 +422,8 @@
      * search around the hinted index as an optimization.
      */
     @VisibleForTesting
-    public int findIndexHinted(String iface, int uid, int set, int tag, int hintIndex) {
+    public int findIndexHinted(String iface, int uid, int set, int tag, int roaming,
+            int hintIndex) {
         for (int offset = 0; offset < size; offset++) {
             final int halfOffset = offset / 2;
 
@@ -398,7 +436,7 @@
             }
 
             if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i]
-                    && Objects.equals(iface, this.iface[i])) {
+                    && roaming == this.roaming[i] && Objects.equals(iface, this.iface[i])) {
                 return i;
             }
         }
@@ -412,7 +450,7 @@
      */
     public void spliceOperationsFrom(NetworkStats stats) {
         for (int i = 0; i < size; i++) {
-            final int j = stats.findIndex(iface[i], uid[i], set[i], tag[i]);
+            final int j = stats.findIndex(iface[i], uid[i], set[i], tag[i], roaming[i]);
             if (j == -1) {
                 operations[i] = 0;
             } else {
@@ -502,6 +540,7 @@
         entry.uid = limitUid;
         entry.set = SET_ALL;
         entry.tag = TAG_NONE;
+        entry.roaming = ROAMING_ALL;
         entry.rxBytes = 0;
         entry.rxPackets = 0;
         entry.txBytes = 0;
@@ -596,9 +635,11 @@
             entry.uid = left.uid[i];
             entry.set = left.set[i];
             entry.tag = left.tag[i];
+            entry.roaming = left.roaming[i];
 
             // find remote row that matches, and subtract
-            final int j = right.findIndexHinted(entry.iface, entry.uid, entry.set, entry.tag, i);
+            final int j = right.findIndexHinted(entry.iface, entry.uid, entry.set, entry.tag,
+                    entry.roaming, i);
             if (j == -1) {
                 // newly appearing row, return entire value
                 entry.rxBytes = left.rxBytes[i];
@@ -644,6 +685,7 @@
         entry.uid = UID_ALL;
         entry.set = SET_ALL;
         entry.tag = TAG_NONE;
+        entry.roaming = ROAMING_ALL;
         entry.operations = 0L;
 
         for (int i = 0; i < size; i++) {
@@ -672,6 +714,7 @@
         entry.iface = IFACE_ALL;
         entry.set = SET_ALL;
         entry.tag = TAG_NONE;
+        entry.roaming = ROAMING_ALL;
 
         for (int i = 0; i < size; i++) {
             // skip specific tags, since already counted in TAG_NONE
@@ -717,6 +760,7 @@
             pw.print(" uid="); pw.print(uid[i]);
             pw.print(" set="); pw.print(setToString(set[i]));
             pw.print(" tag="); pw.print(tagToString(tag[i]));
+            pw.print(" roaming="); pw.print(roamingToString(roaming[i]));
             pw.print(" rxBytes="); pw.print(rxBytes[i]);
             pw.print(" rxPackets="); pw.print(rxPackets[i]);
             pw.print(" txBytes="); pw.print(txBytes[i]);
@@ -783,6 +827,22 @@
         return "0x" + Integer.toHexString(tag);
     }
 
+    /**
+     * Return text description of {@link #roaming} value.
+     */
+    public static String roamingToString(int roaming) {
+        switch (roaming) {
+            case ROAMING_ALL:
+                return "ALL";
+            case ROAMING_DEFAULT:
+                return "DEFAULT";
+            case ROAMING_ROAMING:
+                return "ROAMING";
+            default:
+                return "UNKNOWN";
+        }
+    }
+
     @Override
     public String toString() {
         final CharArrayWriter writer = new CharArrayWriter();
@@ -932,6 +992,7 @@
                 tmpEntry.uid = uid[i];
                 tmpEntry.tag = tag[i];
                 tmpEntry.set = set[i];
+                tmpEntry.roaming = roaming[i];
                 combineValues(tmpEntry);
                 if (tag[i] == TAG_NONE) {
                     moved.add(tmpEntry);
@@ -950,16 +1011,24 @@
         moved.set = SET_DBG_VPN_OUT;
         moved.tag = TAG_NONE;
         moved.iface = underlyingIface;
+        moved.roaming = ROAMING_ALL;
         combineValues(moved);
 
         // Caveat: if the vpn software uses tag, the total tagged traffic may be greater than
         // the TAG_NONE traffic.
-        int idxVpnBackground = findIndex(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE);
+        //
+        // Relies on the fact that the underlying traffic only has state ROAMING_DEFAULT, which
+        // should be the case as it comes directly from the /proc file. We only blend in the
+        // roaming data after applying these adjustments, by checking the NetworkIdentity of the
+        // underlying iface.
+        int idxVpnBackground = findIndex(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE,
+                ROAMING_DEFAULT);
         if (idxVpnBackground != -1) {
             tunSubtract(idxVpnBackground, this, moved);
         }
 
-        int idxVpnForeground = findIndex(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE);
+        int idxVpnForeground = findIndex(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE,
+                ROAMING_DEFAULT);
         if (idxVpnForeground != -1) {
             tunSubtract(idxVpnForeground, this, moved);
         }
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index bce38f4..9180506 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -378,6 +378,16 @@
         public abstract long getWifiControllerActivity(int type, int which);
 
         /**
+         * Returns the time in milliseconds that this app kept the Bluetooth controller in the
+         * specified state <code>type</code>.
+         * @param type one of {@link #CONTROLLER_IDLE_TIME}, {@link #CONTROLLER_RX_TIME}, or
+         *             {@link #CONTROLLER_TX_TIME}.
+         * @param which one of {@link #STATS_CURRENT}, {@link #STATS_SINCE_CHARGED}, or
+         *              {@link #STATS_SINCE_UNPLUGGED}.
+         */
+        public abstract long getBluetoothControllerActivity(int type, int which);
+
+        /**
          * {@hide}
          */
         public abstract int getUid();
@@ -2014,7 +2024,9 @@
     public static final int NETWORK_MOBILE_TX_DATA = 1;
     public static final int NETWORK_WIFI_RX_DATA = 2;
     public static final int NETWORK_WIFI_TX_DATA = 3;
-    public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_WIFI_TX_DATA + 1;
+    public static final int NETWORK_BT_RX_DATA = 4;
+    public static final int NETWORK_BT_TX_DATA = 5;
+    public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_BT_TX_DATA + 1;
 
     public abstract long getNetworkActivityBytes(int type, int which);
     public abstract long getNetworkActivityPackets(int type, int which);
@@ -3284,6 +3296,8 @@
         final long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
         final long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
         final long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
+        final long btRxTotalBytes = getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
+        final long btTxTotalBytes = getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
 
         if (fullWakeLockTimeTotalMicros != 0) {
             sb.setLength(0);
@@ -3517,6 +3531,10 @@
         sb.append("mAh");
         pw.println(sb.toString());
 
+        pw.print(prefix);
+        pw.print("  Bluetooth total received: "); pw.print(formatBytesLocked(btRxTotalBytes));
+        pw.print(", sent: "); pw.println(formatBytesLocked(btTxTotalBytes));
+
         final long bluetoothIdleTimeMs =
                 getBluetoothControllerActivity(CONTROLLER_IDLE_TIME, which);
         final long bluetoothRxTimeMs = getBluetoothControllerActivity(CONTROLLER_RX_TIME, which);
@@ -3838,12 +3856,17 @@
             final long mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
             final long wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
             final long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
+            final long btRxBytes = u.getNetworkActivityBytes(NETWORK_BT_RX_DATA, which);
+            final long btTxBytes = u.getNetworkActivityBytes(NETWORK_BT_TX_DATA, which);
+
             final long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
             final long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
-            final long uidMobileActiveTime = u.getMobileRadioActiveTime(which);
-            final int uidMobileActiveCount = u.getMobileRadioActiveCount(which);
             final long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
             final long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
+
+            final long uidMobileActiveTime = u.getMobileRadioActiveTime(which);
+            final int uidMobileActiveCount = u.getMobileRadioActiveCount(which);
+
             final long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
             final long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
             final int wifiScanCount = u.getWifiScanCount(which);
@@ -3923,6 +3946,37 @@
                 pw.println(sb.toString());
             }
 
+            if (btRxBytes > 0 || btTxBytes > 0) {
+                pw.print(prefix); pw.print("    Bluetooth network: ");
+                pw.print(formatBytesLocked(btRxBytes)); pw.print(" received, ");
+                pw.print(formatBytesLocked(btTxBytes));
+                pw.println(" sent");
+            }
+
+            final long uidBtIdleTimeMs = u.getBluetoothControllerActivity(CONTROLLER_IDLE_TIME,
+                    which);
+            final long uidBtRxTimeMs = u.getBluetoothControllerActivity(CONTROLLER_RX_TIME, which);
+            final long uidBtTxTimeMs = u.getBluetoothControllerActivity(CONTROLLER_TX_TIME, which);
+            final long uidBtTotalTimeMs = uidBtIdleTimeMs + uidBtRxTimeMs + uidBtTxTimeMs;
+            if (uidBtTotalTimeMs > 0) {
+                sb.setLength(0);
+                sb.append(prefix).append("    Bluetooth Idle time: ");
+                formatTimeMs(sb, uidBtIdleTimeMs);
+                sb.append("(").append(formatRatioLocked(uidBtIdleTimeMs, uidBtTotalTimeMs))
+                        .append(")\n");
+
+                sb.append(prefix).append("    Bluetooth Rx time:   ");
+                formatTimeMs(sb, uidBtRxTimeMs);
+                sb.append("(").append(formatRatioLocked(uidBtRxTimeMs, uidBtTotalTimeMs))
+                        .append(")\n");
+
+                sb.append(prefix).append("    Bluetooth Tx time:   ");
+                formatTimeMs(sb, uidBtTxTimeMs);
+                sb.append("(").append(formatRatioLocked(uidBtTxTimeMs, uidBtTotalTimeMs))
+                        .append(")");
+                pw.println(sb.toString());
+            }
+
             if (u.hasUserActivity()) {
                 boolean hasData = false;
                 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index f01f597..fe834a1 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -529,6 +529,21 @@
     public static final String DISALLOW_DATA_ROAMING = "no_data_roaming";
 
     /**
+     * Specifies if a user is not allowed to change their icon. Device owner and profile owner
+     * can set this restriction. When it is set by device owner, only the target user will be
+     * affected. The default value is <code>false</code>.
+     *
+     * <p>Key for user restrictions.
+     *
+     * <p>Type: Boolean
+     *
+     * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
+     * @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
+     * @see #getUserRestrictions()
+     */
+    public static final String DISALLOW_SET_USER_ICON = "no_set_user_icon";
+
+    /**
      * Allows apps in the parent profile to handle web links from the managed profile.
      *
      * This user restriction has an effect only in a managed profile.
diff --git a/core/java/android/os/UserManagerInternal.java b/core/java/android/os/UserManagerInternal.java
index 898b6cf..f765336 100644
--- a/core/java/android/os/UserManagerInternal.java
+++ b/core/java/android/os/UserManagerInternal.java
@@ -17,6 +17,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.graphics.Bitmap;
 
 /**
  * @hide Only for use within the system server.
@@ -81,4 +82,13 @@
      * whether the user is managed by profile owner.
      */
     public abstract void setUserManaged(int userId, boolean isManaged);
+
+    /**
+     * Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} to omit
+     * restriction check, because DevicePolicyManager must always be able to set user icon
+     * regardless of any restriction.
+     * Also called by {@link com.android.server.pm.UserManagerService} because the logic of setting
+     * the icon is in this method.
+     */
+    public abstract void setUserIcon(int userId, Bitmap bitmap);
 }
diff --git a/core/java/android/print/PrintFileDocumentAdapter.java b/core/java/android/print/PrintFileDocumentAdapter.java
index 5d655bf..747400d 100644
--- a/core/java/android/print/PrintFileDocumentAdapter.java
+++ b/core/java/android/print/PrintFileDocumentAdapter.java
@@ -46,7 +46,7 @@
  */
 public class PrintFileDocumentAdapter extends PrintDocumentAdapter {
 
-    private static final String LOG_TAG = "PrintedFileDocumentAdapter";
+    private static final String LOG_TAG = "PrintedFileDocAdapter";
 
     private final Context mContext;
 
diff --git a/core/java/android/printservice/CustomPrinterIconCallback.java b/core/java/android/printservice/CustomPrinterIconCallback.java
index ea9ea8b..6b9d0d8 100644
--- a/core/java/android/printservice/CustomPrinterIconCallback.java
+++ b/core/java/android/printservice/CustomPrinterIconCallback.java
@@ -31,7 +31,7 @@
     /** The printer the call back is for */
     private final @NonNull PrinterId mPrinterId;
     private final @NonNull IPrintServiceClient mObserver;
-    private static final String LOG_TAG = "CustomPrinterIconCallback";
+    private static final String LOG_TAG = "CustomPrinterIconCB";
 
     /**
      * Create a callback class to be used once a icon is loaded
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 6a5d857c..e7c4a07 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -38,6 +38,7 @@
 import android.telecom.TelecomManager;
 import android.telephony.PhoneNumberUtils;
 import android.text.TextUtils;
+import android.util.Log;
 
 import com.android.internal.telephony.CallerInfo;
 import com.android.internal.telephony.PhoneConstants;
@@ -49,6 +50,7 @@
  */
 public class CallLog {
     private static final String LOG_TAG = "CallLog";
+    private static final boolean VERBOSE_LOG = false; // DON'T SUBMIT WITH TRUE.
 
     public static final String AUTHORITY = "call_log";
 
@@ -58,6 +60,17 @@
     public static final Uri CONTENT_URI =
         Uri.parse("content://" + AUTHORITY);
 
+
+    /**
+     * The "shadow" provider stores calllog when the real calllog provider is encrypted.  The
+     * real provider will alter copy from it when it starts, and remove the entries in the shadow.
+     *
+     * <p>See the comment in {@link Calls#addCall} for the details.
+     *
+     * @hide
+     */
+    public static final String SHADOW_AUTHORITY = "call_log_shadow";
+
     /**
      * Contains the recent calls.
      */
@@ -68,6 +81,10 @@
         public static final Uri CONTENT_URI =
                 Uri.parse("content://call_log/calls");
 
+        /** @hide */
+        public static final Uri SHADOW_CONTENT_URI =
+                Uri.parse("content://call_log_shadow/calls");
+
         /**
          * The content:// style URL for filtering this table on phone numbers
          */
@@ -458,8 +475,10 @@
         public static Uri addCall(CallerInfo ci, Context context, String number,
                 int presentation, int callType, int features, PhoneAccountHandle accountHandle,
                 long start, int duration, Long dataUsage) {
-            return addCall(ci, context, number, "", presentation, callType, features, accountHandle,
-                    start, duration, dataUsage, false, null, false);
+            return addCall(ci, context, number, /* postDialDigits =*/ "", presentation,
+                    callType, features, accountHandle,
+                    start, duration, dataUsage, /* addForAllUsers =*/ false,
+                    /* userToBeInsertedTo =*/ null, /* is_read =*/ false);
         }
 
 
@@ -495,7 +514,7 @@
                 boolean addForAllUsers, UserHandle userToBeInsertedTo) {
             return addCall(ci, context, number, postDialDigits, presentation, callType, features,
                     accountHandle, start, duration, dataUsage, addForAllUsers, userToBeInsertedTo,
-                    false);
+                    /* is_read =*/ false);
         }
 
         /**
@@ -526,13 +545,18 @@
          *                Used for call log restore of missed calls.
          *
          * @result The URI of the call log entry belonging to the user that made or received this
-         *        call.
+         *        call.  This could be of the shadow provider.  Do not return it to non-system apps,
+         *        as they don't have permissions.
          * {@hide}
          */
         public static Uri addCall(CallerInfo ci, Context context, String number,
                 String postDialDigits, int presentation, int callType, int features,
                 PhoneAccountHandle accountHandle, long start, int duration, Long dataUsage,
                 boolean addForAllUsers, UserHandle userToBeInsertedTo, boolean is_read) {
+            if (VERBOSE_LOG) {
+                Log.v(LOG_TAG, String.format("Add call: number=%s, user=%s, for all=%s",
+                        number, userToBeInsertedTo, addForAllUsers));
+            }
             final ContentResolver resolver = context.getContentResolver();
             int numberPresentation = PRESENTATION_ALLOWED;
 
@@ -647,41 +671,104 @@
                 }
             }
 
+            /*
+                Writing the calllog works in the following way:
+                - All user entries
+                    - if user-0 is encrypted, insert to user-0's shadow only.
+                      (other users should also be encrypted, so nothing to do for other users.)
+                    - if user-0 is decrypted, insert to user-0's real provider, as well as
+                      all other users that are running and decrypted and should have calllog.
+
+                - Single user entry.
+                    - If the target user is encryted, insert to its shadow.
+                    - Otherwise insert to its real provider.
+
+                When the (real) calllog provider starts, it copies entries that it missed from
+                elsewhere.
+                - When user-0's (real) provider starts, it copies from user-0's shadow, and clears
+                  the shadow.
+
+                - When other users (real) providers start, unless it shouldn't have calllog entries,
+                     - Copy from the user's shadow, and clears the shadow.
+                     - Copy from user-0's entries that are FOR_ALL_USERS = 1.  (and don't clear it.)
+             */
+
             Uri result = null;
 
+            final UserManager userManager = context.getSystemService(UserManager.class);
+            final int currentUserId = userManager.getUserHandle();
+
             if (addForAllUsers) {
-                // Insert the entry for all currently running users, in order to trigger any
-                // ContentObservers currently set on the call log.
-                final UserManager userManager = (UserManager) context.getSystemService(
-                        Context.USER_SERVICE);
-                List<UserInfo> users = userManager.getUsers(true);
-                final int currentUserId = userManager.getUserHandle();
+                // First, insert to the system user.
+                final Uri uriForSystem = addEntryAndRemoveExpiredEntries(
+                        context, userManager, UserHandle.SYSTEM, values);
+                if (uriForSystem == null
+                        || SHADOW_AUTHORITY.equals(uriForSystem.getAuthority())) {
+                    // This means the system user is still encrypted and the entry has inserted
+                    // into the shadow.  This means other users are still all encrypted.
+                    // Nothing further to do; just return null.
+                    return null;
+                }
+                if (UserHandle.USER_SYSTEM == currentUserId) {
+                    result = uriForSystem;
+                }
+
+                // Otherwise, insert to all other users that are running and unlocked.
+
+                final List<UserInfo> users = userManager.getUsers(true);
+
                 final int count = users.size();
                 for (int i = 0; i < count; i++) {
-                    final UserInfo user = users.get(i);
-                    final UserHandle userHandle = user.getUserHandle();
+                    final UserInfo userInfo = users.get(i);
+                    final UserHandle userHandle = userInfo.getUserHandle();
+                    final int userId = userHandle.getIdentifier();
+
+                    if (userHandle.isSystem()) {
+                        // Already written.
+                        continue;
+                    }
+
+                    if (!shouldHaveSharedCallLogEntries(context, userManager, userId)) {
+                        // Shouldn't have calllog entries.
+                        continue;
+                    }
+
+                    // For other users, we write only when they're running *and* decrypted.
+                    // Other providers will copy from the system user's real provider, when they
+                    // start.
                     if (userManager.isUserRunning(userHandle)
-                            && !userManager.hasUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS,
-                                    userHandle)
-                            && !user.isManagedProfile()) {
-                        Uri uri = addEntryAndRemoveExpiredEntries(context,
-                                ContentProvider.maybeAddUserId(CONTENT_URI, user.id), values);
-                        if (user.id == currentUserId) {
+                            && userManager.isUserUnlocked(userHandle)) {
+                        final Uri uri = addEntryAndRemoveExpiredEntries(context, userManager,
+                                userHandle, values);
+                        if (userId == currentUserId) {
                             result = uri;
                         }
                     }
                 }
             } else {
-                Uri uri = CONTENT_URI;
-                if (userToBeInsertedTo != null) {
-                    uri = ContentProvider
-                            .maybeAddUserId(CONTENT_URI, userToBeInsertedTo.getIdentifier());
-                }
-                result = addEntryAndRemoveExpiredEntries(context, uri, values);
+                // Single-user entry. Just write to that user, assuming it's running.  If the
+                // user is encrypted, we write to the shadow calllog.
+
+                final UserHandle targetUserHandle = userToBeInsertedTo != null
+                        ? userToBeInsertedTo
+                        : UserHandle.of(currentUserId);
+                result = addEntryAndRemoveExpiredEntries(context, userManager, targetUserHandle,
+                        values);
             }
             return result;
         }
 
+        /** @hide */
+        public static boolean shouldHaveSharedCallLogEntries(Context context,
+                UserManager userManager, int userId) {
+            if (userManager.hasUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS,
+                    UserHandle.of(userId))) {
+                return false;
+            }
+            final UserInfo userInfo = userManager.getUserInfo(userId);
+            return userInfo != null && !userInfo.isManagedProfile();
+        }
+
         /**
          * Query the call log database for the last dialed number.
          * @param context Used to get the content resolver.
@@ -707,14 +794,31 @@
             }
         }
 
-        private static Uri addEntryAndRemoveExpiredEntries(Context context, Uri uri,
-                ContentValues values) {
+        private static Uri addEntryAndRemoveExpiredEntries(Context context, UserManager userManager,
+                UserHandle user, ContentValues values) {
             final ContentResolver resolver = context.getContentResolver();
-            Uri result = resolver.insert(uri, values);
-            resolver.delete(uri, "_id IN " +
-                    "(SELECT _id FROM calls ORDER BY " + DEFAULT_SORT_ORDER
-                    + " LIMIT -1 OFFSET 500)", null);
-            return result;
+
+            final Uri uri = ContentProvider.maybeAddUserId(
+                    userManager.isUserUnlocked(user) ? CONTENT_URI : SHADOW_CONTENT_URI,
+                    user.getIdentifier());
+
+            if (VERBOSE_LOG) {
+                Log.v(LOG_TAG, String.format("Inserting to %s", uri));
+            }
+
+            try {
+                final Uri result = resolver.insert(uri, values);
+                resolver.delete(uri, "_id IN " +
+                        "(SELECT _id FROM calls ORDER BY " + DEFAULT_SORT_ORDER
+                        + " LIMIT -1 OFFSET 500)", null);
+                return result;
+            } catch (IllegalArgumentException e) {
+                Log.w(LOG_TAG, "Failed to insert calllog", e);
+                // Even though we make sure the target user is running and decrypted before calling
+                // this method, there's a chance that the user just got shut down, in which case
+                // we'll still get "IllegalArgumentException: Unknown URL content://call_log/calls".
+                return null;
+            }
         }
 
         private static void updateDataUsageStatForData(ContentResolver resolver, String dataId) {
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 2c4241b..692d848 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1826,7 +1826,11 @@
             return ArrayUtils.emptyArray(type);
         }
 
-        return text.getSpans(start, end, type);
+        if(text instanceof SpannableStringBuilder) {
+            return ((SpannableStringBuilder) text).getSpans(start, end, type, false);
+        } else {
+            return text.getSpans(start, end, type);
+        }
     }
 
     private char getEllipsisChar(TextUtils.TruncateAt method) {
diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java
index 4267238..e34560b8 100644
--- a/core/java/android/text/SpannableStringBuilder.java
+++ b/core/java/android/text/SpannableStringBuilder.java
@@ -19,6 +19,7 @@
 import android.annotation.Nullable;
 import android.graphics.Canvas;
 import android.graphics.Paint;
+import android.text.style.ParagraphStyle;
 import android.util.Log;
 
 import com.android.internal.util.ArrayUtils;
@@ -66,11 +67,15 @@
         TextUtils.getChars(text, start, end, mText, 0);
 
         mSpanCount = 0;
+        mSpanInsertCount = 0;
         mSpans = EmptyArray.OBJECT;
         mSpanStarts = EmptyArray.INT;
         mSpanEnds = EmptyArray.INT;
         mSpanFlags = EmptyArray.INT;
         mSpanMax = EmptyArray.INT;
+        mSpanOrder = EmptyArray.INT;
+        mPrioSortBuffer = EmptyArray.INT;
+        mOrderSortBuffer = EmptyArray.INT;
 
         if (text instanceof Spanned) {
             Spanned sp = (Spanned) text;
@@ -234,6 +239,7 @@
     // Documentation from interface
     public void clear() {
         replace(0, length(), "", 0, 0);
+        mSpanInsertCount = 0;
     }
 
     // Documentation from interface
@@ -256,6 +262,7 @@
         if (mIndexOfSpan != null) {
             mIndexOfSpan.clear();
         }
+        mSpanInsertCount = 0;
     }
 
     // Documentation from interface
@@ -485,6 +492,7 @@
         System.arraycopy(mSpanStarts, i + 1, mSpanStarts, i, count);
         System.arraycopy(mSpanEnds, i + 1, mSpanEnds, i, count);
         System.arraycopy(mSpanFlags, i + 1, mSpanFlags, i, count);
+        System.arraycopy(mSpanOrder, i + 1, mSpanOrder, i, count);
 
         mSpanCount--;
 
@@ -712,9 +720,6 @@
                 end += mGapLength;
         }
 
-        int count = mSpanCount;
-        Object[] spans = mSpans;
-
         if (mIndexOfSpan != null) {
             Integer index = mIndexOfSpan.get(what);
             if (index != null) {
@@ -744,8 +749,10 @@
         mSpanStarts = GrowingArrayUtils.append(mSpanStarts, mSpanCount, start);
         mSpanEnds = GrowingArrayUtils.append(mSpanEnds, mSpanCount, end);
         mSpanFlags = GrowingArrayUtils.append(mSpanFlags, mSpanCount, flags);
+        mSpanOrder = GrowingArrayUtils.append(mSpanOrder, mSpanCount, mSpanInsertCount);
         invalidateIndex(mSpanCount);
         mSpanCount++;
+        mSpanInsertCount++;
         // Make sure there is enough room for empty interior nodes.
         // This magic formula computes the size of the smallest perfect binary
         // tree no smaller than mSpanCount.
@@ -837,6 +844,25 @@
      */
     @SuppressWarnings("unchecked")
     public <T> T[] getSpans(int queryStart, int queryEnd, @Nullable Class<T> kind) {
+        return getSpans(queryStart, queryEnd, kind, true);
+    }
+
+    /**
+     * Return an array of the spans of the specified type that overlap
+     * the specified range of the buffer.  The kind may be Object.class to get
+     * a list of all the spans regardless of type.
+     *
+     * @param queryStart Start index.
+     * @param queryEnd End index.
+     * @param kind Class type to search for.
+     * @param sort If true the results are sorted by the insertion order.
+     * @param <T>
+     * @return Array of the spans. Empty array if no results are found.
+     *
+     * @hide
+     */
+    public <T> T[] getSpans(int queryStart, int queryEnd, @Nullable Class<T> kind,
+                                 boolean sort) {
         if (kind == null) return (T[]) ArrayUtils.emptyArray(Object.class);
         if (mSpanCount == 0) return ArrayUtils.emptyArray(kind);
         int count = countSpans(queryStart, queryEnd, kind, treeRoot());
@@ -846,7 +872,13 @@
 
         // Safe conversion, but requires a suppressWarning
         T[] ret = (T[]) Array.newInstance(kind, count);
-        getSpansRec(queryStart, queryEnd, kind, treeRoot(), ret, 0);
+        if (sort) {
+            mPrioSortBuffer = checkSortBuffer(mPrioSortBuffer, count);
+            mOrderSortBuffer = checkSortBuffer(mOrderSortBuffer, count);
+        }
+        getSpansRec(queryStart, queryEnd, kind, treeRoot(), ret, mPrioSortBuffer,
+                mOrderSortBuffer, 0, sort);
+        if (sort) sort(ret, mPrioSortBuffer, mOrderSortBuffer);
         return ret;
     }
 
@@ -876,7 +908,7 @@
                 if (spanEnd >= queryStart &&
                     (spanStart == spanEnd || queryStart == queryEnd ||
                         (spanStart != queryEnd && spanEnd != queryStart)) &&
-                        kind.isInstance(mSpans[i])) {
+                        (Object.class == kind || kind.isInstance(mSpans[i]))) {
                     count++;
                 }
                 if ((i & 1) != 0) {
@@ -887,9 +919,25 @@
         return count;
     }
 
+    /**
+     * Fills the result array with the spans found under the current interval tree node.
+     *
+     * @param queryStart Start index for the interval query.
+     * @param queryEnd End index for the interval query.
+     * @param kind Class type to search for.
+     * @param i Index of the current tree node.
+     * @param ret Array to be filled with results.
+     * @param priority Buffer to keep record of the priorities of spans found.
+     * @param insertionOrder Buffer to keep record of the insertion orders of spans found.
+     * @param count The number of found spans.
+     * @param sort Flag to fill the priority and insertion order buffers. If false then
+     *             the spans with priority flag will be sorted in the result array.
+     * @param <T>
+     * @return The total number of spans found.
+     */
     @SuppressWarnings("unchecked")
     private <T> int getSpansRec(int queryStart, int queryEnd, Class<T> kind,
-            int i, T[] ret, int count) {
+            int i, T[] ret, int[] priority, int[] insertionOrder, int count, boolean sort) {
         if ((i & 1) != 0) {
             // internal tree node
             int left = leftChild(i);
@@ -898,7 +946,8 @@
                 spanMax -= mGapLength;
             }
             if (spanMax >= queryStart) {
-                count = getSpansRec(queryStart, queryEnd, kind, left, ret, count);
+                count = getSpansRec(queryStart, queryEnd, kind, left, ret, priority,
+                        insertionOrder, count, sort);
             }
         }
         if (i >= mSpanCount) return count;
@@ -914,36 +963,137 @@
             if (spanEnd >= queryStart &&
                     (spanStart == spanEnd || queryStart == queryEnd ||
                         (spanStart != queryEnd && spanEnd != queryStart)) &&
-                        kind.isInstance(mSpans[i])) {
-                int prio = mSpanFlags[i] & SPAN_PRIORITY;
-                if (prio != 0) {
-                    int j;
-
-                    for (j = 0; j < count; j++) {
-                        int p = getSpanFlags(ret[j]) & SPAN_PRIORITY;
-
-                        if (prio > p) {
-                            break;
-                        }
-                    }
-
-                    System.arraycopy(ret, j, ret, j + 1, count - j);
-                    // Safe conversion thanks to the isInstance test above
-                    ret[j] = (T) mSpans[i];
-                } else {
-                    // Safe conversion thanks to the isInstance test above
+                        (Object.class == kind || kind.isInstance(mSpans[i]))) {
+                int spanPriority = mSpanFlags[i] & SPAN_PRIORITY;
+                if(sort) {
                     ret[count] = (T) mSpans[i];
+                    priority[count] = spanPriority;
+                    insertionOrder[count] = mSpanOrder[i];
+                } else if (spanPriority != 0) {
+                    //insertion sort for elements with priority
+                    int j = 0;
+                    for (; j < count; j++) {
+                        int p = getSpanFlags(ret[j]) & SPAN_PRIORITY;
+                        if (spanPriority > p) break;
+                    }
+                    System.arraycopy(ret, j, ret, j + 1, count - j);
+                    ret[j] = (T) mSpans[i];
                 }
                 count++;
             }
             if (count < ret.length && (i & 1) != 0) {
-                count = getSpansRec(queryStart, queryEnd, kind, rightChild(i), ret, count);
+                count = getSpansRec(queryStart, queryEnd, kind, rightChild(i), ret, priority,
+                        insertionOrder, count, sort);
             }
         }
         return count;
     }
 
     /**
+     * Check the size of the buffer and grow if required.
+     *
+     * @param buffer Buffer to be checked.
+     * @param size Required size.
+     * @return Same buffer instance if the current size is greater than required size. Otherwise a
+     * new instance is created and returned.
+     */
+    private final int[] checkSortBuffer(int[] buffer, int size) {
+        if(size > buffer.length) {
+            return ArrayUtils.newUnpaddedIntArray(GrowingArrayUtils.growSize(size));
+        }
+        return buffer;
+    }
+
+    /**
+     * An iterative heap sort implementation. It will sort the spans using first their priority
+     * then insertion order. A span with higher priority will be before a span with lower
+     * priority. If priorities are the same, the spans will be sorted with insertion order. A
+     * span with a lower insertion order will be before a span with a higher insertion order.
+     *
+     * @param array Span array to be sorted.
+     * @param priority Priorities of the spans
+     * @param insertionOrder Insertion orders of the spans
+     * @param <T> Span object type.
+     * @param <T>
+     */
+    private final <T> void sort(T[] array, int[] priority, int[] insertionOrder) {
+        int size = array.length;
+        for (int i = size / 2 - 1; i >= 0; i--) {
+            siftDown(i, array, size, priority, insertionOrder);
+        }
+
+        for (int i = size - 1; i > 0; i--) {
+            T v = array[0];
+            int prio = priority[0];
+            int insertOrder = insertionOrder[0];
+            array[0] = array[i];
+            priority[0] = priority[i];
+            insertionOrder[0] = insertionOrder[i];
+            siftDown(0, array, i, priority, insertionOrder);
+            array[i] = v;
+            priority[i] = prio;
+            insertionOrder[i] = insertOrder;
+        }
+    }
+
+    /**
+     * Helper function for heap sort.
+     *
+     * @param index Index of the element to sift down.
+     * @param array Span array to be sorted.
+     * @param size Current heap size.
+     * @param priority Priorities of the spans
+     * @param insertionOrder Insertion orders of the spans
+     * @param <T> Span object type.
+     */
+    private final <T> void siftDown(int index, T[] array, int size, int[] priority,
+                                    int[] insertionOrder) {
+        T v = array[index];
+        int prio = priority[index];
+        int insertOrder = insertionOrder[index];
+
+        int left = 2 * index + 1;
+        while (left < size) {
+            if (left < size - 1 && compareSpans(left, left + 1, priority, insertionOrder) < 0) {
+                left++;
+            }
+            if (compareSpans(index, left, priority, insertionOrder) >= 0) {
+                break;
+            }
+            array[index] = array[left];
+            priority[index] = priority[left];
+            insertionOrder[index] = insertionOrder[left];
+            index = left;
+            left = 2 * index + 1;
+        }
+        array[index] = v;
+        priority[index] = prio;
+        insertionOrder[index] = insertOrder;
+    }
+
+    /**
+     * Compare two span elements in an array. Comparison is based first on the priority flag of
+     * the span, and then the insertion order of the span.
+     *
+     * @param left Index of the element to compare.
+     * @param right Index of the other element to compare.
+     * @param priority Priorities of the spans
+     * @param insertionOrder Insertion orders of the spans
+     * @return
+     */
+    private final int compareSpans(int left, int right, int[] priority,
+                                       int[] insertionOrder) {
+        int priority1 = priority[left];
+        int priority2 = priority[right];
+        if (priority1 == priority2) {
+            return Integer.compare(insertionOrder[left], insertionOrder[right]);
+        }
+        // since high priority has to be before a lower priority, the arguments to compare are
+        // opposite of the insertion order check.
+        return Integer.compare(priority2, priority1);
+    }
+
+    /**
      * Return the next offset after <code>start</code> but less than or
      * equal to <code>limit</code> where a span of the specified type
      * begins or ends.
@@ -1509,18 +1659,21 @@
                 int start = mSpanStarts[i];
                 int end = mSpanEnds[i];
                 int flags = mSpanFlags[i];
+                int insertionOrder = mSpanOrder[i];
                 int j = i;
                 do {
                     mSpans[j] = mSpans[j - 1];
                     mSpanStarts[j] = mSpanStarts[j - 1];
                     mSpanEnds[j] = mSpanEnds[j - 1];
                     mSpanFlags[j] = mSpanFlags[j - 1];
+                    mSpanOrder[j] = mSpanOrder[j - 1];
                     j--;
                 } while (j > 0 && start < mSpanStarts[j - 1]);
                 mSpans[j] = span;
                 mSpanStarts[j] = start;
                 mSpanEnds[j] = end;
                 mSpanFlags[j] = flags;
+                mSpanOrder[j] = insertionOrder;
                 invalidateIndex(j);
             }
         }
@@ -1558,6 +1711,11 @@
     private int[] mSpanEnds;
     private int[] mSpanMax;  // see calcMax() for an explanation of what this array stores
     private int[] mSpanFlags;
+    private int[] mSpanOrder;  // store the order of span insertion
+    private int mSpanInsertCount;  // counter for the span insertion
+    private int[] mPrioSortBuffer;  // buffer used to sort getSpans result
+    private int[] mOrderSortBuffer;  // buffer used to sort getSpans result
+
     private int mSpanCount;
     private IdentityHashMap<Object, Integer> mIndexOfSpan;
     private int mLowWaterMark;  // indices below this have not been touched
diff --git a/core/java/android/text/SpannableStringInternal.java b/core/java/android/text/SpannableStringInternal.java
index 5c5deb4..47e71be 100644
--- a/core/java/android/text/SpannableStringInternal.java
+++ b/core/java/android/text/SpannableStringInternal.java
@@ -36,24 +36,99 @@
         mSpanData = EmptyArray.INT;
 
         if (source instanceof Spanned) {
-            Spanned sp = (Spanned) source;
-            Object[] spans = sp.getSpans(start, end, Object.class);
-
-            for (int i = 0; i < spans.length; i++) {
-                int st = sp.getSpanStart(spans[i]);
-                int en = sp.getSpanEnd(spans[i]);
-                int fl = sp.getSpanFlags(spans[i]);
-
-                if (st < start)
-                    st = start;
-                if (en > end)
-                    en = end;
-
-                setSpan(spans[i], st - start, en - start, fl);
+            if (source instanceof SpannableStringInternal) {
+                copySpans((SpannableStringInternal) source, start, end);
+            } else {
+                copySpans((Spanned) source, start, end);
             }
         }
     }
 
+    /**
+     * Copies another {@link Spanned} object's spans between [start, end] into this object.
+     *
+     * @param src Source object to copy from.
+     * @param start Start index in the source object.
+     * @param end End index in the source object.
+     */
+    private final void copySpans(Spanned src, int start, int end) {
+        Object[] spans = src.getSpans(start, end, Object.class);
+
+        for (int i = 0; i < spans.length; i++) {
+            int st = src.getSpanStart(spans[i]);
+            int en = src.getSpanEnd(spans[i]);
+            int fl = src.getSpanFlags(spans[i]);
+
+            if (st < start)
+                st = start;
+            if (en > end)
+                en = end;
+
+            setSpan(spans[i], st - start, en - start, fl);
+        }
+    }
+
+    /**
+     * Copies a {@link SpannableStringInternal} object's spans between [start, end] into this
+     * object.
+     *
+     * @param src Source object to copy from.
+     * @param start Start index in the source object.
+     * @param end End index in the source object.
+     */
+    private final void copySpans(SpannableStringInternal src, int start, int end) {
+        if (start == 0 && end == src.length()) {
+            mSpans = ArrayUtils.newUnpaddedObjectArray(src.mSpans.length);
+            mSpanData = new int[src.mSpanData.length];
+            mSpanCount = src.mSpanCount;
+            System.arraycopy(src.mSpans, 0, mSpans, 0, src.mSpans.length);
+            System.arraycopy(src.mSpanData, 0, mSpanData, 0, mSpanData.length);
+        } else {
+            int count = 0;
+            int[] srcData = src.mSpanData;
+            int limit = src.mSpanCount;
+            for (int i = 0; i < limit; i++) {
+                int spanStart = srcData[i * COLUMNS + START];
+                int spanEnd = srcData[i * COLUMNS + END];
+                if (isOutOfCopyRange(start, end, spanStart, spanEnd)) continue;
+                count++;
+            }
+
+            if (count == 0) return;
+
+            Object[] srcSpans = src.mSpans;
+            mSpanCount = count;
+            mSpans = ArrayUtils.newUnpaddedObjectArray(mSpanCount);
+            mSpanData = new int[mSpanCount * COLUMNS];
+            for (int i = 0, j = 0; i < limit; i++) {
+                int spanStart = srcData[i * COLUMNS + START];
+                int spanEnd = srcData[i * COLUMNS + END];
+                if (isOutOfCopyRange(start, end, spanStart, spanEnd)) continue;
+                if (spanStart < start) spanStart = start;
+                if (spanEnd > end) spanEnd = end;
+
+                mSpans[j] = srcSpans[i];
+                mSpanData[j * COLUMNS + START] = spanStart - start;
+                mSpanData[j * COLUMNS + END] = spanEnd - start;
+                mSpanData[j * COLUMNS + FLAGS] = srcData[i * COLUMNS + FLAGS];
+                j++;
+            }
+        }
+    }
+
+    /**
+     * Checks if [spanStart, spanEnd] interval is excluded from [start, end].
+     *
+     * @return True if excluded, false if included.
+     */
+    private final boolean isOutOfCopyRange(int start, int end, int spanStart, int spanEnd) {
+        if (spanStart > end || spanEnd < start) return true;
+        if (spanStart != spanEnd && start != end) {
+            if (spanStart == end || spanEnd == start) return true;
+        }
+        return false;
+    }
+
     public final int length() {
         return mText.length();
     }
@@ -234,7 +309,7 @@
             }
 
             // verify span class as late as possible, since it is expensive
-            if (kind != null && !kind.isInstance(spans[i])) {
+            if (kind != null && kind != Object.class && !kind.isInstance(spans[i])) {
                 continue;
             }
 
diff --git a/core/java/android/util/LocaleList.java b/core/java/android/util/LocaleList.java
index 24883e3..8a2d015 100644
--- a/core/java/android/util/LocaleList.java
+++ b/core/java/android/util/LocaleList.java
@@ -301,10 +301,19 @@
             // is a pseudo-locale. So this is not a match.
             return 0;
         }
+        final String supportedScr = getLikelyScript(supported);
+        if (supportedScr.isEmpty()) {
+            // If we can't guess a script, we don't know enough about the locales' language to find
+            // if the locales match. So we fall back to old behavior of matching, which considered
+            // locales with different regions different.
+            final String supportedRegion = supported.getCountry();
+            return (supportedRegion.isEmpty() ||
+                    supportedRegion.equals(desired.getCountry()))
+                    ? 1 : 0;
+        }
+        final String desiredScr = getLikelyScript(desired);
         // 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;
     }
 
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 0981e69..9f6d3e5 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -499,7 +499,8 @@
                     mLayout.privateFlags |=
                             WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
                 }
-                mLayout.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
+                mLayout.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION
+                    | WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
 
                 if (mWindow == null) {
                     Display display = getDisplay();
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 0b8018b..b5b0baa 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6691,6 +6691,68 @@
         }
 
         info.addAction(AccessibilityAction.ACTION_SHOW_ON_SCREEN);
+        populateAccessibilityNodeInfoDrawingOrderInParent(info);
+    }
+
+    /**
+     * Determine the order in which this view will be drawn relative to its siblings for a11y
+     *
+     * @param info The info whose drawing order should be populated
+     */
+    private void populateAccessibilityNodeInfoDrawingOrderInParent(AccessibilityNodeInfo info) {
+        int drawingOrderInParent = 1;
+        // Iterate up the hierarchy if parents are not important for a11y
+        View viewAtDrawingLevel = this;
+        final ViewParent parent = getParentForAccessibility();
+        while (viewAtDrawingLevel != parent) {
+            final ViewParent currentParent = viewAtDrawingLevel.getParent();
+            if (!(currentParent instanceof ViewGroup)) {
+                // Should only happen for the Decor
+                drawingOrderInParent = 0;
+                break;
+            } else {
+                final ViewGroup parentGroup = (ViewGroup) currentParent;
+                final int childCount = parentGroup.getChildCount();
+                if (childCount > 1) {
+                    List<View> preorderedList = parentGroup.buildOrderedChildList();
+                    if (preorderedList != null) {
+                        final int childDrawIndex = preorderedList.indexOf(viewAtDrawingLevel);
+                        for (int i = 0; i < childDrawIndex; i++) {
+                            drawingOrderInParent += numViewsForAccessibility(preorderedList.get(i));
+                        }
+                    } else {
+                        final int childIndex = parentGroup.indexOfChild(viewAtDrawingLevel);
+                        final boolean customOrder = parentGroup.isChildrenDrawingOrderEnabled();
+                        final int childDrawIndex = ((childIndex >= 0) && customOrder) ? parentGroup
+                                .getChildDrawingOrder(childCount, childIndex) : childIndex;
+                        final int numChildrenToIterate = customOrder ? childCount : childDrawIndex;
+                        if (childDrawIndex != 0) {
+                            for (int i = 0; i < numChildrenToIterate; i++) {
+                                final int otherDrawIndex = (customOrder ?
+                                        parentGroup.getChildDrawingOrder(childCount, i) : i);
+                                if (otherDrawIndex < childDrawIndex) {
+                                    drawingOrderInParent +=
+                                            numViewsForAccessibility(parentGroup.getChildAt(i));
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            viewAtDrawingLevel = (View) currentParent;
+        }
+        info.setDrawingOrder(drawingOrderInParent);
+    }
+
+    private static int numViewsForAccessibility(View view) {
+        if (view != null) {
+            if (view.includeForAccessibility()) {
+                return 1;
+            } else if (view instanceof ViewGroup) {
+                return ((ViewGroup) view).getNumChildrenForAccessibility();
+            }
+        }
+        return 0;
     }
 
     private View findLabelForView(View view, int labeledId) {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index f674298..868ddda 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -700,9 +700,6 @@
         mGroupFlags |= (focusability & FLAG_MASK_FOCUSABILITY);
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     void handleFocusGainInternal(int direction, Rect previouslyFocusedRect) {
         if (mFocused != null) {
@@ -712,9 +709,7 @@
         super.handleFocusGainInternal(direction, previouslyFocusedRect);
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    @Override
     public void requestChildFocus(View child, View focused) {
         if (DBG) {
             System.out.println(this + " requestChildFocus()");
@@ -739,9 +734,7 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    @Override
     public void focusableViewAvailable(View v) {
         if (mParent != null
                 // shortcut: don't report a new focusable view if we block our descendants from
@@ -760,9 +753,7 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    @Override
     public boolean showContextMenuForChild(View originalView) {
         return mParent != null && mParent.showContextMenuForChild(originalView);
     }
@@ -772,9 +763,6 @@
         return mParent != null && mParent.showContextMenuForChild(originalView, x, y);
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public ActionMode startActionModeForChild(View originalView, ActionMode.Callback callback) {
         if ((mGroupFlags & FLAG_START_ACTION_MODE_FOR_CHILD_IS_TYPED) == 0) {
@@ -791,9 +779,6 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public ActionMode startActionModeForChild(
             View originalView, ActionMode.Callback callback, int type) {
@@ -848,6 +833,7 @@
      * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, and
      *        FOCUS_RIGHT, or 0 for not applicable.
      */
+    @Override
     public View focusSearch(View focused, int direction) {
         if (isRootNamespace()) {
             // root namespace means we should consider ourselves the top of the
@@ -860,16 +846,11 @@
         return null;
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    @Override
     public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {
         return false;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public boolean requestSendAccessibilityEvent(View child, AccessibilityEvent event) {
         ViewParent parent = mParent;
@@ -921,6 +902,7 @@
     /**
      * Called when a child view has changed whether or not it is tracking transient state.
      */
+    @Override
     public void childHasTransientStateChanged(View child, boolean childHasTransientState) {
         final boolean oldHasTransientState = hasTransientState();
         if (childHasTransientState) {
@@ -945,18 +927,13 @@
         return mChildCountWithTransientState > 0 || super.hasTransientState();
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public boolean dispatchUnhandledMove(View focused, int direction) {
         return mFocused != null &&
                 mFocused.dispatchUnhandledMove(focused, direction);
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    @Override
     public void clearChildFocus(View child) {
         if (DBG) {
             System.out.println(this + " clearChildFocus()");
@@ -968,9 +945,6 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public void clearFocus() {
         if (DBG) {
@@ -985,9 +959,6 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     void unFocus(View focused) {
         if (DBG) {
@@ -1054,9 +1025,6 @@
         return null;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public boolean hasFocusable() {
         if ((mViewFlags & VISIBILITY_MASK) != VISIBLE) {
@@ -1083,9 +1051,6 @@
         return false;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
         final int focusableCount = views.size();
@@ -1195,9 +1160,6 @@
         return null;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public void dispatchWindowFocusChanged(boolean hasFocus) {
         super.dispatchWindowFocusChanged(hasFocus);
@@ -1208,9 +1170,6 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public void addTouchables(ArrayList<View> views) {
         super.addTouchables(views);
@@ -1239,9 +1198,6 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public void dispatchDisplayHint(int hint) {
         super.dispatchDisplayHint(hint);
@@ -1287,9 +1243,6 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     protected void dispatchVisibilityChanged(View changedView, int visibility) {
         super.dispatchVisibilityChanged(changedView, visibility);
@@ -1300,9 +1253,6 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public void dispatchWindowVisibilityChanged(int visibility) {
         super.dispatchWindowVisibilityChanged(visibility);
@@ -1313,9 +1263,6 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public void dispatchConfigurationChanged(Configuration newConfig) {
         super.dispatchConfigurationChanged(newConfig);
@@ -1326,9 +1273,7 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    @Override
     public void recomputeViewAttributes(View child) {
         if (mAttachInfo != null && !mAttachInfo.mRecomputeGlobalAttributes) {
             ViewParent parent = mParent;
@@ -1350,9 +1295,7 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    @Override
     public void bringChildToFront(View child) {
         final int index = indexOfChild(child);
         if (index >= 0) {
@@ -1369,9 +1312,6 @@
         return mLocalPoint;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     // TODO: Write real docs
     @Override
     public boolean dispatchDragEvent(DragEvent event) {
@@ -1631,9 +1571,6 @@
         return changed;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public boolean dispatchKeyEventPreIme(KeyEvent event) {
         if ((mPrivateFlags & (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS))
@@ -1646,9 +1583,6 @@
         return false;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public boolean dispatchKeyEvent(KeyEvent event) {
         if (mInputEventConsistencyVerifier != null) {
@@ -1673,9 +1607,6 @@
         return false;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public boolean dispatchKeyShortcutEvent(KeyEvent event) {
         if ((mPrivateFlags & (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS))
@@ -1688,9 +1619,6 @@
         return false;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public boolean dispatchTrackballEvent(MotionEvent event) {
         if (mInputEventConsistencyVerifier != null) {
@@ -1744,9 +1672,6 @@
         return super.getPointerIcon(event, x, y);
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @SuppressWarnings({"ConstantConditions"})
     @Override
     protected boolean dispatchHoverEvent(MotionEvent event) {
@@ -2045,9 +1970,6 @@
         return MotionEvent.obtainNoHistory(event);
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     protected boolean dispatchGenericPointerEvent(MotionEvent event) {
         // Send the event to the child under the pointer.
@@ -2081,9 +2003,6 @@
         return super.dispatchGenericPointerEvent(event);
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     protected boolean dispatchGenericFocusedEvent(MotionEvent event) {
         // Send the event to the focused child or to this view group if it has focus.
@@ -2124,9 +2043,6 @@
         return handled;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public boolean dispatchTouchEvent(MotionEvent ev) {
         if (mInputEventConsistencyVerifier != null) {
@@ -2721,9 +2637,7 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    @Override
     public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
 
         if (disallowIntercept == ((mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0)) {
@@ -2893,9 +2807,6 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     void dispatchAttachedToWindow(AttachInfo info, int visibility) {
         mGroupFlags |= FLAG_PREVENT_DISPATCH_ATTACHED_TO_WINDOW;
@@ -2962,6 +2873,7 @@
      * adds in all child views of the view group, in addition to calling the default View
      * implementation.
      */
+    @Override
     public void dispatchProvideStructure(ViewStructure structure) {
         super.dispatchProvideStructure(structure);
         if (!isAssistBlocked()) {
@@ -3083,6 +2995,26 @@
     }
 
     /**
+     * Counts the number of children of this View that will be sent to an accessibility service.
+     *
+     * @return The number of children an {@code AccessibilityNodeInfo} rooted at this View
+     * would have.
+     */
+    int getNumChildrenForAccessibility() {
+        int numChildrenForAccessibility = 0;
+        for (int i = 0; i < getChildCount(); i++) {
+            View child = getChildAt(i);
+            if (child.includeForAccessibility()) {
+                numChildrenForAccessibility++;
+            } else if (child instanceof ViewGroup) {
+                numChildrenForAccessibility += ((ViewGroup) child)
+                        .getNumChildrenForAccessibility();
+            }
+        }
+        return numChildrenForAccessibility;
+    }
+
+    /**
      * {@inheritDoc}
      *
      * <p>Subclasses should always call <code>super.onNestedPrePerformAccessibilityAction</code></p>
@@ -3098,9 +3030,6 @@
         return false;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     void dispatchDetachedFromWindow() {
         // If we still have a touch target, we are still in the process of
@@ -3152,9 +3081,6 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
         super.dispatchSaveInstanceState(container);
@@ -3180,9 +3106,6 @@
         super.dispatchSaveInstanceState(container);
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
         super.dispatchRestoreInstanceState(container);
@@ -3255,6 +3178,7 @@
         return mLayoutMode == LAYOUT_MODE_OPTICAL_BOUNDS;
     }
 
+    @Override
     Insets computeOpticalInsets() {
         if (isLayoutModeOptical()) {
             int left = 0;
@@ -3386,9 +3310,6 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     protected void dispatchDraw(Canvas canvas) {
         boolean usingRenderNodeProperties = canvas.isRecordingFor(mRenderNode);
@@ -3514,6 +3435,7 @@
             // drawChild() after the animation is over
             mGroupFlags |= FLAG_NOTIFY_ANIMATION_LISTENER;
             final Runnable end = new Runnable() {
+               @Override
                public void run() {
                    notifyAnimationListener();
                }
@@ -3612,6 +3534,7 @@
 
         if (mAnimationListener != null) {
            final Runnable end = new Runnable() {
+               @Override
                public void run() {
                    mAnimationListener.onAnimationEnd(mLayoutAnimationController.getAnimation());
                }
@@ -3761,9 +3684,6 @@
         return hasBooleanFlag(FLAG_CLIP_TO_PADDING);
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public void dispatchSetSelected(boolean selected) {
         final View[] children = mChildren;
@@ -3773,9 +3693,6 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public void dispatchSetActivated(boolean activated) {
         final View[] children = mChildren;
@@ -4180,6 +4097,7 @@
      * @param child the child view to add
      * @param params the layout parameters to set on the child
      */
+    @Override
     public void addView(View child, LayoutParams params) {
         addView(child, -1, params);
     }
@@ -4212,9 +4130,7 @@
         addViewInner(child, index, params, false);
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    @Override
     public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
         if (!checkLayoutParams(params)) {
             throw new IllegalArgumentException("Invalid LayoutParams supplied to " + this);
@@ -4225,9 +4141,6 @@
         view.setLayoutParams(params);
     }
 
-    /**
-     * {@inheritDoc}
-     */
     protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
         return  p != null;
     }
@@ -4574,6 +4487,7 @@
      * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)},
      * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p>
      */
+    @Override
     public void removeView(View view) {
         if (removeViewInternal(view)) {
             requestLayout();
@@ -5075,6 +4989,7 @@
      * Don't call or override this method. It is used for the implementation of
      * the view hierarchy.
      */
+    @Override
     public final void invalidateChild(View child, final Rect dirty) {
         ViewParent parent = this;
 
@@ -5183,6 +5098,7 @@
      * if this ViewGroup is already fully invalidated or if the dirty rectangle
      * does not intersect with this ViewGroup's bounds.
      */
+    @Override
     public ViewParent invalidateChildInParent(final int[] location, final Rect dirty) {
         if ((mPrivateFlags & PFLAG_DRAWN) == PFLAG_DRAWN ||
                 (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) {
@@ -5476,9 +5392,7 @@
         notifySubtreeAccessibilityStateChangedIfNeeded();
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    @Override
     public boolean getChildVisibleRect(View child, Rect r, android.graphics.Point offset) {
         // It doesn't make a whole lot of sense to call this on a view that isn't attached,
         // but for some simple tests it can be useful. If we don't have attach info this
@@ -5538,9 +5452,6 @@
         return rectIsVisible;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public final void layout(int l, int t, int r, int b) {
         if (!mSuppressLayout && (mTransition == null || !mTransition.isChangingLayout())) {
@@ -5554,9 +5465,6 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     protected abstract void onLayout(boolean changed,
             int l, int t, int r, int b);
@@ -5921,9 +5829,6 @@
         return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     protected void debug(int depth) {
         super.debug(depth);
@@ -6340,9 +6245,6 @@
         return mSuppressLayout;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     public boolean gatherTransparentRegion(Region region) {
         // If no transparent regions requested, we are always opaque.
@@ -6366,9 +6268,7 @@
         return meOpaque || noneOfTheChildrenAreTransparent;
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    @Override
     public void requestTransparentRegion(View child) {
         if (child != null) {
             child.mPrivateFlags |= View.PFLAG_REQUEST_TRANSPARENT_REGIONS;
@@ -6494,6 +6394,7 @@
      * If {@link #addStatesFromChildren} is true, refreshes this group's
      * drawable state (to include the states from its children).
      */
+    @Override
     public void childDrawableStateChanged(View child) {
         if ((mGroupFlags & FLAG_ADD_STATES_FROM_CHILDREN) != 0) {
             refreshDrawableState();
@@ -7239,9 +7140,6 @@
             a.recycle();
         }
 
-        /**
-         * {@inheritDoc}
-         */
         public MarginLayoutParams(int width, int height) {
             super(width, height);
 
@@ -7271,9 +7169,6 @@
             this.mMarginFlags = source.mMarginFlags;
         }
 
-        /**
-         * {@inheritDoc}
-         */
         public MarginLayoutParams(LayoutParams source) {
             super(source);
 
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 9c19bf1..1bb0311 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1251,13 +1251,16 @@
             if (mTmpValue.type == TypedValue.TYPE_DIMENSION) {
                 baseSize = (int)mTmpValue.getDimension(packageMetrics);
             }
-            if (DEBUG_DIALOG) Log.v(mTag, "Window " + mView + ": baseSize=" + baseSize);
+            if (DEBUG_DIALOG) Log.v(mTag, "Window " + mView + ": baseSize=" + baseSize
+                    + ", desiredWindowWidth=" + desiredWindowWidth);
             if (baseSize != 0 && desiredWindowWidth > baseSize) {
                 childWidthMeasureSpec = getRootMeasureSpec(baseSize, lp.width);
                 childHeightMeasureSpec = getRootMeasureSpec(desiredWindowHeight, lp.height);
                 performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
                 if (DEBUG_DIALOG) Log.v(mTag, "Window " + mView + ": measured ("
-                        + host.getMeasuredWidth() + "," + host.getMeasuredHeight() + ")");
+                        + host.getMeasuredWidth() + "," + host.getMeasuredHeight()
+                        + ") from width spec: " + MeasureSpec.toString(childWidthMeasureSpec)
+                        + " and height spec: " + MeasureSpec.toString(childHeightMeasureSpec));
                 if ((host.getMeasuredWidthAndState()&View.MEASURED_STATE_TOO_SMALL) == 0) {
                     goodMeasure = true;
                 } else {
@@ -3586,9 +3589,7 @@
 
         // tell the window manager
         try {
-            if (!isInLocalFocusMode()) {
-                mWindowSession.setInTouchMode(inTouchMode);
-            }
+            mWindowSession.setInTouchMode(inTouchMode);
         } catch (RemoteException e) {
             throw new RuntimeException(e);
         }
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 1735e1b..1327ea1 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -647,6 +647,7 @@
     private int mBooleanProperties;
     private final Rect mBoundsInParent = new Rect();
     private final Rect mBoundsInScreen = new Rect();
+    private int mDrawingOrderInParent;
 
     private CharSequence mPackageName;
     private CharSequence mClassName;
@@ -1892,6 +1893,37 @@
     }
 
     /**
+     * Get the drawing order of the view corresponding it this node.
+     * <p>
+     * Drawing order is determined only within the node's parent, so this index is only relative
+     * to its siblings.
+     * <p>
+     * In some cases, the drawing order is essentially simultaneous, so it is possible for two
+     * siblings to return the same value. It is also possible that values will be skipped.
+     *
+     * @return The drawing position of the view corresponding to this node relative to its siblings.
+     */
+    public int getDrawingOrder() {
+        return mDrawingOrderInParent;
+    }
+
+    /**
+     * Set the drawing order of the view corresponding it this node.
+     *
+     * <p>
+     *   <strong>Note:</strong> Cannot be called from an
+     *   {@link android.accessibilityservice.AccessibilityService}.
+     *   This class is made immutable before being delivered to an AccessibilityService.
+     * </p>
+     * @param drawingOrderInParent
+     * @throws IllegalStateException If called from an AccessibilityService.
+     */
+    public void setDrawingOrder(int drawingOrderInParent) {
+        enforceNotSealed();
+        mDrawingOrderInParent = drawingOrderInParent;
+    }
+
+    /**
      * Gets the collection info if the node is a collection. A collection
      * child is always a collection item.
      *
@@ -2753,6 +2785,7 @@
         parcel.writeInt(mTextSelectionEnd);
         parcel.writeInt(mInputType);
         parcel.writeInt(mLiveRegion);
+        parcel.writeInt(mDrawingOrderInParent);
 
         if (mExtras != null) {
             parcel.writeInt(1);
@@ -2850,6 +2883,7 @@
         mTextSelectionEnd = other.mTextSelectionEnd;
         mInputType = other.mInputType;
         mLiveRegion = other.mLiveRegion;
+        mDrawingOrderInParent = other.mDrawingOrderInParent;
         if (other.mExtras != null && !other.mExtras.isEmpty()) {
             getExtras().putAll(other.mExtras);
         }
@@ -2927,6 +2961,7 @@
 
         mInputType = parcel.readInt();
         mLiveRegion = parcel.readInt();
+        mDrawingOrderInParent = parcel.readInt();
 
         if (parcel.readInt() == 1) {
             getExtras().putAll(parcel.readBundle());
@@ -2982,6 +3017,7 @@
         mBoundsInParent.set(0, 0, 0, 0);
         mBoundsInScreen.set(0, 0, 0, 0);
         mBooleanProperties = 0;
+        mDrawingOrderInParent = 0;
         mPackageName = null;
         mClassName = null;
         mText = null;
diff --git a/core/java/android/webkit/TokenBindingService.java b/core/java/android/webkit/TokenBindingService.java
index a6d7b4a..f11ce51 100644
--- a/core/java/android/webkit/TokenBindingService.java
+++ b/core/java/android/webkit/TokenBindingService.java
@@ -30,6 +30,7 @@
  * attached to the View hierarchy.
  * @hide
  */
+@SystemApi
 public abstract class TokenBindingService {
 
     public static final String KEY_ALGORITHM_RSA2048_PKCS_1_5 = "RSA2048_PKCS_1.5";
diff --git a/core/java/android/webkit/WebViewFactoryProvider.java b/core/java/android/webkit/WebViewFactoryProvider.java
index 02c911f..2b66a83 100644
--- a/core/java/android/webkit/WebViewFactoryProvider.java
+++ b/core/java/android/webkit/WebViewFactoryProvider.java
@@ -107,7 +107,6 @@
      * implementation must return the same instance on subsequent calls.
      *
      * @return the TokenBindingService instance
-     * @hide
      */
     TokenBindingService getTokenBindingService();
 
diff --git a/core/java/android/widget/DropDownListView.java b/core/java/android/widget/DropDownListView.java
index 02f7e7a..69e4218 100644
--- a/core/java/android/widget/DropDownListView.java
+++ b/core/java/android/widget/DropDownListView.java
@@ -75,6 +75,12 @@
     private AbsListViewAutoScroller mScrollHelper;
 
     /**
+     * Runnable posted when we are awaiting hover event resolution. When set,
+     * drawable state changes are postponed.
+     */
+    private ResolveHoverRunnable mResolveHoverRunnable;
+
+    /**
      * Creates a new list view wrapper.
      *
      * @param context this view's context
@@ -101,18 +107,36 @@
     }
 
     @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        if (mResolveHoverRunnable != null) {
+            // Resolved hover event as hover => touch transition.
+            mResolveHoverRunnable.cancel();
+        }
+
+        return super.onTouchEvent(ev);
+    }
+
+    @Override
     public boolean onHoverEvent(@NonNull MotionEvent ev) {
+        final int action = ev.getActionMasked();
+        if (action == MotionEvent.ACTION_HOVER_EXIT && mResolveHoverRunnable == null) {
+            // This may be transitioning to TOUCH_DOWN. Postpone drawable state
+            // updates until either the next frame or the next touch event.
+            mResolveHoverRunnable = new ResolveHoverRunnable();
+            mResolveHoverRunnable.post();
+        }
+
         // Allow the super class to handle hover state management first.
         final boolean handled = super.onHoverEvent(ev);
 
-        final int action = ev.getActionMasked();
         if (action == MotionEvent.ACTION_HOVER_ENTER
                 || action == MotionEvent.ACTION_HOVER_MOVE) {
             final int position = pointToPosition((int) ev.getX(), (int) ev.getY());
             if (position != INVALID_POSITION && position != mSelectedPosition) {
                 final View hoveredItem = getChildAt(position - getFirstVisiblePosition());
                 if (hoveredItem.isEnabled()) {
-                    // Force a focus so that the proper selector state gets used when we update.
+                    // Force a focus so that the proper selector state gets
+                    // used when we update.
                     requestFocus();
 
                     positionSelector(position, hoveredItem);
@@ -122,7 +146,8 @@
                 updateSelectorState();
             }
         } else {
-            // Do not cancel the selected position if the selection is visible by other reasons.
+            // Do not cancel the selected position if the selection is visible
+            // by other means.
             if (!super.shouldShowSelector()) {
                 setSelectedPositionInt(INVALID_POSITION);
                 setNextSelectedPositionInt(INVALID_POSITION);
@@ -132,6 +157,13 @@
         return handled;
     }
 
+    @Override
+    protected void drawableStateChanged() {
+        if (mResolveHoverRunnable == null) {
+            super.drawableStateChanged();
+        }
+    }
+
     /**
      * Handles forwarded events.
      *
@@ -196,12 +228,14 @@
     }
 
     /**
-     * Sets whether the list selection is hidden, as part of a workaround for a touch mode issue
-     * (see the declaration for mListSelectionHidden).
-     * @param listSelectionHidden
+     * Sets whether the list selection is hidden, as part of a workaround for a
+     * touch mode issue (see the declaration for mListSelectionHidden).
+     *
+     * @param hideListSelection {@code true} to hide list selection,
+     *                          {@code false} to show
      */
-    public void setListSelectionHidden(boolean listSelectionHidden) {
-        this.mListSelectionHidden = listSelectionHidden;
+    public void setListSelectionHidden(boolean hideListSelection) {
+        mListSelectionHidden = hideListSelection;
     }
 
     private void clearPressedItem() {
@@ -312,4 +346,25 @@
     public boolean hasFocus() {
         return mHijackFocus || super.hasFocus();
     }
+
+    /**
+     * Runnable that forces hover event resolution and updates drawable state.
+     */
+    private class ResolveHoverRunnable implements Runnable {
+        @Override
+        public void run() {
+            // Resolved hover event as standard hover exit.
+            mResolveHoverRunnable = null;
+            drawableStateChanged();
+        }
+
+        public void cancel() {
+            mResolveHoverRunnable = null;
+            removeCallbacks(this);
+        }
+
+        public void post() {
+            DropDownListView.this.post(this);
+        }
+    }
 }
\ No newline at end of file
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 1576877..df5af25 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -38,6 +38,7 @@
 import android.graphics.Path;
 import android.graphics.Rect;
 import android.graphics.RectF;
+import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.Parcel;
@@ -3098,10 +3099,6 @@
         private SuggestionSpan mMisspelledSpan;
 
         private class CustomPopupWindow extends PopupWindow {
-            public CustomPopupWindow(Context context, int defStyleAttr) {
-                super(context, null, defStyleAttr);
-            }
-
             @Override
             public void dismiss() {
                 if (!isShowing()) {
@@ -3126,9 +3123,9 @@
 
         @Override
         protected void createPopupWindow() {
-            mPopupWindow = new CustomPopupWindow(mTextView.getContext(),
-                com.android.internal.R.attr.textSuggestionsWindowStyle);
+            mPopupWindow = new CustomPopupWindow();
             mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
+            mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
             mPopupWindow.setFocusable(true);
             mPopupWindow.setClippingEnabled(false);
         }
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index f6e6186..e0ef86c 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -1781,6 +1781,16 @@
         }
     }
 
+    /**
+     * Returns the current gravity. See {@link android.view.Gravity}
+     *
+     * @return the current gravity.
+     * @see #setGravity
+     */
+    public int getGravity() {
+        return mGravity;
+    }
+
     @android.view.RemotableViewMethod
     public void setHorizontalGravity(int horizontalGravity) {
         final int gravity = horizontalGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index d46c6f9..7535caa 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -645,6 +645,16 @@
      */
     private Editor mEditor;
 
+    private static final int DEVICE_PROVISIONED_UNKNOWN = 0;
+    private static final int DEVICE_PROVISIONED_NO = 1;
+    private static final int DEVICE_PROVISIONED_YES = 2;
+
+    /**
+     * Some special options such as sharing selected text should only be shown if the device
+     * is provisioned. Only check the provisioned state once for a given view instance.
+     */
+    private int mDeviceProvisionedState = DEVICE_PROVISIONED_UNKNOWN;
+
     /*
      * Kick-start the font cache for the zygote process (to pay the cost of
      * initializing freetype for our default font only once).
@@ -6440,6 +6450,9 @@
                 outAttrs.imeOptions |= EditorInfo.IME_FLAG_NO_ENTER_ACTION;
             }
             outAttrs.hintText = mHint;
+            // LocaleList is designed to be immutable.  This is theoretically equivalent to copy
+            // the snapshot of the current text locales.
+            outAttrs.locales = getTextLocales();
             if (mText instanceof Editable) {
                 InputConnection ic = new EditableInputConnection(this);
                 outAttrs.initialSelStart = getSelectionStart();
@@ -6447,9 +6460,6 @@
                 outAttrs.initialCapsMode = ic.getCursorCapsMode(getInputType());
                 return ic;
             }
-            // LocaleList is designed to be immutable.  This is theoretically equivalent to copy
-            // the snapshot of the current text locales.
-            outAttrs.locales = getTextLocales();
         }
         return null;
     }
@@ -9613,7 +9623,17 @@
     }
 
     boolean canShare() {
-        return canCopy();
+        return canCopy() && isDeviceProvisioned();
+    }
+
+    boolean isDeviceProvisioned() {
+        if (mDeviceProvisionedState == DEVICE_PROVISIONED_UNKNOWN) {
+            mDeviceProvisionedState = Settings.Global.getInt(
+                    mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0
+                    ? DEVICE_PROVISIONED_YES
+                    : DEVICE_PROVISIONED_NO;
+        }
+        return mDeviceProvisionedState == DEVICE_PROVISIONED_YES;
     }
 
     boolean canPaste() {
diff --git a/core/java/android/widget/VideoView.java b/core/java/android/widget/VideoView.java
index 2671739..f084db2 100644
--- a/core/java/android/widget/VideoView.java
+++ b/core/java/android/widget/VideoView.java
@@ -22,6 +22,7 @@
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.media.AudioManager;
+import android.media.Cea708CaptionRenderer;
 import android.media.ClosedCaptionRenderer;
 import android.media.MediaFormat;
 import android.media.MediaPlayer;
@@ -328,6 +329,7 @@
                     context, mMediaPlayer.getMediaTimeProvider(), mMediaPlayer);
             controller.registerRenderer(new WebVttRenderer(context));
             controller.registerRenderer(new TtmlRenderer(context));
+            controller.registerRenderer(new Cea708CaptionRenderer(context));
             controller.registerRenderer(new ClosedCaptionRenderer(context));
             mMediaPlayer.setSubtitleAnchor(controller, this);
 
diff --git a/core/java/com/android/internal/app/ConfirmUserCreationActivity.java b/core/java/com/android/internal/app/ConfirmUserCreationActivity.java
index df9cf43..53d7793 100644
--- a/core/java/com/android/internal/app/ConfirmUserCreationActivity.java
+++ b/core/java/com/android/internal/app/ConfirmUserCreationActivity.java
@@ -26,6 +26,7 @@
 import android.content.pm.UserInfo;
 import android.os.Bundle;
 import android.os.PersistableBundle;
+import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.Log;
 
@@ -91,7 +92,8 @@
         }
         final String message;
         // Check the user restrictions
-        boolean cantCreateUser = mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER);
+        boolean cantCreateUser = mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)
+                || !mUserManager.isAdminUser();
         // Check the system state and user count
         boolean cantCreateAnyMoreUsers = !mUserManager.canAddMoreUsers();
         // Check the account existence
diff --git a/core/java/com/android/internal/app/LocaleHelper.java b/core/java/com/android/internal/app/LocaleHelper.java
new file mode 100644
index 0000000..5ac786a
--- /dev/null
+++ b/core/java/com/android/internal/app/LocaleHelper.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.icu.util.ULocale;
+import android.util.LocaleList;
+
+import java.text.Collator;
+import java.util.Comparator;
+import java.util.Locale;
+
+/**
+ * This class implements some handy methods to proces with locales.
+ */
+public class LocaleHelper {
+
+    /**
+     * Sentence-case (first character uppercased).
+     *
+     * <p>There is no good API available for this, not even in ICU.
+     * We can revisit this if we get some ICU support later.</p>
+     *
+     * <p>There are currently several tickets requesting this feature:</p>
+     * <ul>
+     * <li>ICU needs to provide an easy way to titlecase only one first letter
+     *   http://bugs.icu-project.org/trac/ticket/11729</li>
+     * <li>Add "initial case"
+     *    http://bugs.icu-project.org/trac/ticket/8394</li>
+     * <li>Add code for initialCase, toTitlecase don't modify after Lt,
+     *   avoid 49Ers, low-level language-specific casing
+     *   http://bugs.icu-project.org/trac/ticket/10410</li>
+     * <li>BreakIterator.getFirstInstance: Often you need to titlecase just the first
+     *   word, and leave the rest of the string alone.  (closed as duplicate)
+     *   http://bugs.icu-project.org/trac/ticket/8946</li>
+     * </ul>
+     *
+     * <p>A (clunky) option with the current ICU API is:</p>
+     * {{
+     *   BreakIterator breakIterator = BreakIterator.getSentenceInstance(locale);
+     *   String result = UCharacter.toTitleCase(locale,
+     *       source, breakIterator, UCharacter.TITLECASE_NO_LOWERCASE);
+     * }}
+     *
+     * <p>That also means creating BreakIteratos for each locale. Expensive...</p>
+     *
+     * @param str the string to sentence-case.
+     * @param locale the locale used for the case conversion.
+     * @return the string converted to sentence-case.
+     */
+    public static String toSentenceCase(String str, Locale locale) {
+        if (str.isEmpty()) {
+            return str;
+        }
+        final int firstCodePointLen = str.offsetByCodePoints(0, 1);
+        return str.substring(0, firstCodePointLen).toUpperCase(locale)
+                + str.substring(firstCodePointLen);
+    }
+
+    /**
+     * Normalizes a string for locale name search. Does case conversion for now,
+     * but might do more in the future.
+     *
+     * <p>Warning: it is only intended to be used in searches by the locale picker.
+     * Don't use it for other things, it is very limited.</p>
+     *
+     * @param str the string to normalize
+     * @param locale the locale that might be used for certain operations (i.e. case conversion)
+     * @return the string normalized for search
+     */
+    public static String normalizeForSearch(String str, Locale locale) {
+        // TODO: tbd if it needs to be smarter (real normalization, remove accents, etc.)
+        // If needed we might use case folding and ICU/CLDR's collation-based loose searching.
+        // TODO: decide what should the locale be, the default locale, or the locale of the string.
+        // Uppercase is better than lowercase because of things like sharp S, Greek sigma, ...
+        return str.toUpperCase();
+    }
+
+    /**
+     * Returns the locale localized for display in the provided locale.
+     *
+     * @param locale the locale whose name is to be displayed.
+     * @param displayLocale the locale in which to display the name.
+     * @param sentenceCase true if the result should be sentence-cased
+     * @return the localized name of the locale.
+     */
+    public static String getDisplayName(Locale locale, Locale displayLocale, boolean sentenceCase) {
+        String result = ULocale.getDisplayName(locale.toLanguageTag(),
+                ULocale.forLocale(displayLocale));
+        return sentenceCase ? toSentenceCase(result, displayLocale) : result;
+    }
+
+    /**
+     * Returns the locale localized for display in the default locale.
+     *
+     * @param locale the locale whose name is to be displayed.
+     * @param sentenceCase true if the result should be sentence-cased
+     * @return the localized name of the locale.
+     */
+    public static String getDisplayName(Locale locale, boolean sentenceCase) {
+        String result = ULocale.getDisplayName(locale.toLanguageTag(), ULocale.getDefault());
+        return sentenceCase ? toSentenceCase(result, Locale.getDefault()) : result;
+    }
+
+    /**
+     * Returns a locale's country localized for display in the provided locale.
+     *
+     * @param locale the locale whose country will be displayed.
+     * @param displayLocale the locale in which to display the name.
+     * @return the localized country name.
+     */
+    public static String getDisplayCountry(Locale locale, Locale displayLocale) {
+        return ULocale.getDisplayCountry(locale.toLanguageTag(), ULocale.forLocale(displayLocale));
+    }
+
+    /**
+     * Returns a locale's country localized for display in the default locale.
+     *
+     * @param locale the locale whose country will be displayed.
+     * @return the localized country name.
+     */
+    public static String getDisplayCountry(Locale locale) {
+        return ULocale.getDisplayCountry(locale.toLanguageTag(), ULocale.getDefault());
+    }
+
+    /**
+     * Returns the locale list localized for display in the provided locale.
+     *
+     * @param locales the list of locales whose names is to be displayed.
+     * @param displayLocale the locale in which to display the names.
+     *                      If this is null, it will use the default locale.
+     * @return the locale aware list of locale names
+     */
+    public static String getDisplayLocaleList(LocaleList locales, Locale displayLocale) {
+        final StringBuilder result = new StringBuilder();
+
+        final Locale dispLocale = displayLocale == null ? Locale.getDefault() : displayLocale;
+        int localeCount = locales.size();
+        for (int i = 0; i < localeCount; i++) {
+            Locale locale = locales.get(i);
+            result.append(LocaleHelper.getDisplayName(locale, dispLocale, false));
+            // TODO: language aware list formatter. ICU has one.
+            if (i < localeCount - 1) {
+                result.append(", ");
+            }
+        }
+
+        return result.toString();
+    }
+
+    /**
+     * Adds the likely subtags for a provided locale ID.
+     *
+     * @param locale the locale to maximize.
+     * @return the maximized Locale instance.
+     */
+    public static Locale addLikelySubtags(Locale locale) {
+        return libcore.icu.ICU.addLikelySubtags(locale);
+    }
+
+    /**
+     * Locale-sensitive comparison for LocaleInfo.
+     *
+     * <p>It uses the label, leaving the decision on what to put there to the LocaleInfo.
+     * For instance fr-CA can be shown as "français" as a generic label in the language selection,
+     * or "français (Canada)" if it is a suggestion, or "Canada" in the country selection.</p>
+     *
+     * <p>Gives priority to suggested locales (to sort them at the top).</p>
+     */
+    static final class LocaleInfoComparator implements Comparator<LocaleStore.LocaleInfo> {
+        private final Collator mCollator;
+
+        /**
+         * Constructor.
+         *
+         * @param sortLocale the locale to be used for sorting.
+         */
+        public LocaleInfoComparator(Locale sortLocale) {
+            mCollator = Collator.getInstance(sortLocale);
+        }
+
+        /**
+         * Compares its two arguments for order.
+         *
+         * @param lhs   the first object to be compared
+         * @param rhs   the second object to be compared
+         * @return  a negative integer, zero, or a positive integer as the first
+         *          argument is less than, equal to, or greater than the second.
+         */
+        @Override
+        public int compare(LocaleStore.LocaleInfo lhs, LocaleStore.LocaleInfo rhs) {
+            // We don't care about the various suggestion types, just "suggested" (!= 0)
+            // and "all others" (== 0)
+            if (lhs.isSuggested() == rhs.isSuggested()) {
+                // They are in the same "bucket" (suggested / others), so we compare the text
+                return mCollator.compare(lhs.getLabel(), rhs.getLabel());
+            } else {
+                // One locale is suggested and one is not, so we put them in different "buckets"
+                return lhs.isSuggested() ? -1 : 1;
+            }
+        }
+    }
+}
diff --git a/core/java/com/android/internal/app/LocalePickerWithRegion.java b/core/java/com/android/internal/app/LocalePickerWithRegion.java
index 3b8f865..9a17883 100644
--- a/core/java/com/android/internal/app/LocalePickerWithRegion.java
+++ b/core/java/com/android/internal/app/LocalePickerWithRegion.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,189 +16,158 @@
 
 package com.android.internal.app;
 
-import com.android.internal.R;
-
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
 import android.app.ListFragment;
 import android.content.Context;
-import android.content.res.Resources;
 import android.os.Bundle;
-import android.util.ArrayMap;
-import android.view.LayoutInflater;
+import android.util.LocaleList;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
 import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
 import android.widget.ListView;
-import android.widget.TextView;
+import android.widget.SearchView;
 
-import java.text.Collator;
-import java.util.ArrayList;
+import com.android.internal.R;
+
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Locale;
-import java.util.Map;
+import java.util.Set;
 
-class LocaleAdapter extends ArrayAdapter<LocalePicker.LocaleInfo> {
-    final private Map<String, LocalePicker.LocaleInfo> mLevelOne = new ArrayMap<>();
-    final private Map<String, HashSet<LocalePicker.LocaleInfo>> mLevelTwo = new ArrayMap<>();
-    final private LayoutInflater mInflater;
+/**
+ * A two-step locale picker. It shows a language, then a country.
+ *
+ * <p>It shows suggestions at the top, then the rest of the locales.
+ * Allows the user to search for locales using both their native name and their name in the
+ * default locale.</p>
+ */
+public class LocalePickerWithRegion extends ListFragment implements SearchView.OnQueryTextListener {
 
-    final static class LocaleAwareComparator implements Comparator<LocalePicker.LocaleInfo> {
-        private final Collator mCollator;
+    private SuggestedLocaleAdapter mAdapter;
+    private LocaleSelectedListener mListener;
+    private Set<LocaleStore.LocaleInfo> mLocaleList;
+    private LocaleStore.LocaleInfo mParentLocale;
+    private boolean mTranslatedOnly = false;
+    private boolean mCountryMode = false;
 
-        public LocaleAwareComparator(Locale sortLocale) {
-            mCollator = Collator.getInstance(sortLocale);
-        }
-
-        @Override
-        public int compare(LocalePicker.LocaleInfo lhs, LocalePicker.LocaleInfo rhs) {
-            return mCollator.compare(lhs.getLabel(), rhs.getLabel());
-        }
+    /**
+     * Other classes can register to be notified when a locale was selected.
+     *
+     * <p>This is the mechanism to "return" the result of the selection.</p>
+     */
+    public interface LocaleSelectedListener {
+        /**
+         * The classes that want to retrieve the locale picked should implement this method.
+         * @param locale    the locale picked.
+         */
+        void onLocaleSelected(LocaleStore.LocaleInfo locale);
     }
 
-    static List<Locale> getCuratedLocaleList(Context context) {
-        final Resources resources = context.getResources();
-        final String[] supportedLocaleCodes = resources.getStringArray(R.array.supported_locales);
+    private static LocalePickerWithRegion createCountryPicker(Context context,
+            LocaleSelectedListener listener, LocaleStore.LocaleInfo parent,
+            boolean translatedOnly) {
+        LocalePickerWithRegion localePicker = new LocalePickerWithRegion();
+        boolean shouldShowTheList = localePicker.setListener(context, listener, parent,
+                true /* country mode */, translatedOnly);
+        return shouldShowTheList ? localePicker : null;
+    }
 
-        final ArrayList<Locale> result = new ArrayList<>(supportedLocaleCodes.length);
-        for (String localeId : supportedLocaleCodes) {
-            Locale locale = Locale.forLanguageTag(localeId);
-            if (!locale.getCountry().isEmpty()) {
-                result.add(Locale.forLanguageTag(localeId));
+    public static LocalePickerWithRegion createLanguagePicker(Context context,
+            LocaleSelectedListener listener, boolean translatedOnly) {
+        LocalePickerWithRegion localePicker = new LocalePickerWithRegion();
+        localePicker.setListener(context, listener, null,
+                false /* language mode */, translatedOnly);
+        return localePicker;
+    }
+
+    /**
+     * Sets the listener and initializes the locale list.
+     *
+     * <p>Returns true if we need to show the list, false if not.</p>
+     *
+     * <p>Can return false because of an error, trying to show a list of countries,
+     * but no parent locale was provided.</p>
+     *
+     * <p>It can also return false if the caller tries to show the list in country mode and
+     * there is only one country available (i.e. Japanese => Japan).
+     * In this case we don't even show the list, we call the listener with that locale,
+     * "pretending" it was selected, and return false.</p>
+     */
+    private boolean setListener(Context context, LocaleSelectedListener listener,
+            LocaleStore.LocaleInfo parent, boolean countryMode, boolean translatedOnly) {
+        if (countryMode && (parent == null || parent.getLocale() == null)) {
+            // The list of countries is determined as all the countries where the parent language
+            // is used.
+            throw new IllegalArgumentException("The country selection list needs a parent.");
+        }
+
+        this.mCountryMode = countryMode;
+        this.mParentLocale = parent;
+        this.mListener = listener;
+        this.mTranslatedOnly = translatedOnly;
+        setRetainInstance(true);
+
+        final HashSet<String> langTagsToIgnore = new HashSet<>();
+        if (!translatedOnly) {
+            final LocaleList userLocales = LocalePicker.getLocales();
+            final String[] langTags = userLocales.toLanguageTags().split(",");
+            Collections.addAll(langTagsToIgnore, langTags);
+        }
+
+        if (countryMode) {
+            mLocaleList = LocaleStore.getLevelLocales(context,
+                    langTagsToIgnore, parent, translatedOnly);
+            if (mLocaleList.size() <= 1) {
+                if (listener != null && (mLocaleList.size() == 1)) {
+                    listener.onLocaleSelected(mLocaleList.iterator().next());
+                }
+                return false;
             }
+        } else {
+            mLocaleList = LocaleStore.getLevelLocales(context, langTagsToIgnore,
+                    null /* no parent */, translatedOnly);
         }
-        return result;
+
+        return true;
     }
 
-    public LocaleAdapter(Context context) {
-        this(context, getCuratedLocaleList(context));
-    }
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setHasOptionsMenu(true);
 
-    static Locale getBaseLocale(Locale locale) {
-        return new Locale.Builder()
-                .setLocale(locale)
-                .setRegion("")
-                .build();
-    }
-
-    // There is no good API available for this, not even in ICU.
-    // We can revisit this if we get some ICU support later
-    //
-    // There are currently several tickets requesting this feature:
-    // * ICU needs to provide an easy way to titlecase only one first letter
-    //   http://bugs.icu-project.org/trac/ticket/11729
-    // * Add "initial case"
-    //    http://bugs.icu-project.org/trac/ticket/8394
-    // * Add code for initialCase, toTitlecase don't modify after Lt,
-    //   avoid 49Ers, low-level language-specific casing
-    //   http://bugs.icu-project.org/trac/ticket/10410
-    // * BreakIterator.getFirstInstance: Often you need to titlecase just the first
-    //   word, and leave the rest of the string alone.  (closed as duplicate)
-    //   http://bugs.icu-project.org/trac/ticket/8946
-    //
-    // A (clunky) option with the current ICU API is:
-    //   BreakIterator breakIterator = BreakIterator.getSentenceInstance(locale);
-    //   String result = UCharacter.toTitleCase(locale,
-    //       source, breakIterator, UCharacter.TITLECASE_NO_LOWERCASE);
-    // That also means creating BreakIteratos for each locale. Expensive...
-    private static String toTitleCase(String s, Locale locale) {
-        if (s.length() == 0) {
-            return s;
-        }
-        final int firstCodePointLen = s.offsetByCodePoints(0, 1);
-        return s.substring(0, firstCodePointLen).toUpperCase(locale)
-                + s.substring(firstCodePointLen);
-    }
-
-    public LocaleAdapter(Context context, List<Locale> locales) {
-        super(context, R.layout.locale_picker_item, R.id.locale);
-        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
-        for (Locale locale : locales) {
-            Locale baseLocale = getBaseLocale(locale);
-            String language = baseLocale.toLanguageTag();
-            if (!mLevelOne.containsKey(language)) {
-                String label = toTitleCase(baseLocale.getDisplayName(baseLocale), baseLocale);
-                mLevelOne.put(language, new LocalePicker.LocaleInfo(label, baseLocale));
-            }
-
-            final HashSet<LocalePicker.LocaleInfo> subLocales;
-            if (mLevelTwo.containsKey(language)) {
-                subLocales = mLevelTwo.get(language);
+        Locale sortingLocale;
+        if (mCountryMode) {
+            if (mParentLocale == null) {
+                sortingLocale = Locale.getDefault();
+                this.getActivity().setTitle(R.string.country_selection_title);
             } else {
-                subLocales = new HashSet<>();
-                mLevelTwo.put(language, subLocales);
+                sortingLocale = mParentLocale.getLocale();
+                this.getActivity().setTitle(mParentLocale.getFullNameNative());
             }
-            String label = locale.getDisplayCountry(locale);
-            subLocales.add(new LocalePicker.LocaleInfo(label, locale));
-        }
-
-        setAdapterLevel(null);
-    }
-
-    public void setAdapterLevel(String parentLocale) {
-        this.clear();
-
-        if (parentLocale == null) {
-            this.addAll(mLevelOne.values());
         } else {
-            this.addAll(mLevelTwo.get(parentLocale));
+            sortingLocale = Locale.getDefault();
+            this.getActivity().setTitle(R.string.language_selection_title);
         }
 
-        Locale sortLocale = (parentLocale == null)
-                ? Locale.getDefault()
-                : Locale.forLanguageTag(parentLocale);
-        LocaleAwareComparator comparator = new LocaleAwareComparator(sortLocale);
-        this.sort(comparator);
-
-        this.notifyDataSetChanged();
-    }
-
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-        View view;
-        TextView text;
-        if (convertView == null) {
-            view = mInflater.inflate(R.layout.locale_picker_item, parent, false);
-            text = (TextView) view.findViewById(R.id.locale);
-            view.setTag(text);
-        } else {
-            view = convertView;
-            text = (TextView) view.getTag();
-        }
-        LocalePicker.LocaleInfo item = getItem(position);
-        text.setText(item.getLabel());
-        text.setTextLocale(item.getLocale());
-        return view;
-    }
-}
-
-public class LocalePickerWithRegion extends ListFragment {
-    private static final int LIST_MODE_LANGUAGE = 0;
-    private static final int LIST_MODE_COUNTRY = 1;
-
-    private LocaleAdapter mAdapter;
-    private int mDisplayMode = LIST_MODE_LANGUAGE;
-
-    public static interface LocaleSelectionListener {
-        // You can add any argument if you really need it...
-        public void onLocaleSelected(Locale locale);
-    }
-
-    private LocaleSelectionListener mListener = null;
-
-    @Override
-    public void onActivityCreated(final Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-
-        mAdapter = new LocaleAdapter(getContext());
-        mAdapter.setAdapterLevel(null);
+        mAdapter = new SuggestedLocaleAdapter(mLocaleList, mCountryMode);
+        LocaleHelper.LocaleInfoComparator comp =
+                new LocaleHelper.LocaleInfoComparator(sortingLocale);
+        mAdapter.sort(comp);
         setListAdapter(mAdapter);
     }
 
-    public void setLocaleSelectionListener(LocaleSelectionListener listener) {
-        mListener = listener;
+    @Override
+    public boolean onOptionsItemSelected(MenuItem menuItem) {
+        int id = menuItem.getItemId();
+        switch (id) {
+            case android.R.id.home:
+                getFragmentManager().popBackStack();
+                return true;
+        }
+        return super.onOptionsItemSelected(menuItem);
     }
 
     @Override
@@ -207,24 +176,56 @@
         getListView().requestFocus();
     }
 
-    /**
-     * Each listener needs to call {@link LocalePicker.updateLocale(Locale)} to actually
-     * change the locale.
-     * <p/>
-     * We don't call {@link LocalePicker.updateLocale(Locale)} automatically, as it halts
-     * the system for a moment and some callers won't want it.
-     */
     @Override
     public void onListItemClick(ListView l, View v, int position, long id) {
-        final Locale locale = ((LocalePicker.LocaleInfo) getListAdapter().getItem(position)).locale;
-        // TODO: handle the back buttons to return to the language list
-        if (mDisplayMode == LIST_MODE_LANGUAGE) {
-            mDisplayMode = LIST_MODE_COUNTRY;
-            mAdapter.setAdapterLevel(locale.toLanguageTag());
-            return;
+        final LocaleStore.LocaleInfo locale =
+                (LocaleStore.LocaleInfo) getListAdapter().getItem(position);
+
+        if (mCountryMode || locale.getParent() != null) {
+            if (mListener != null) {
+                mListener.onLocaleSelected(locale);
+            }
+            getFragmentManager().popBackStack("localeListEditor",
+                    FragmentManager.POP_BACK_STACK_INCLUSIVE);
+        } else {
+            LocalePickerWithRegion selector = LocalePickerWithRegion.createCountryPicker(
+                    getContext(), mListener, locale, mTranslatedOnly /* translate only */);
+            if (selector != null) {
+                getFragmentManager().beginTransaction()
+                        .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
+                        .replace(getId(), selector).addToBackStack(null)
+                        .commit();
+            } else {
+                getFragmentManager().popBackStack("localeListEditor",
+                        FragmentManager.POP_BACK_STACK_INCLUSIVE);
+            }
         }
-        if (mListener != null) {
-            mListener.onLocaleSelected(locale);
+    }
+
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        if (!mCountryMode) {
+            inflater.inflate(R.menu.language_selection_list, menu);
+
+            MenuItem mSearchMenuItem = menu.findItem(R.id.locale_search_menu);
+            SearchView mSearchView = (SearchView) mSearchMenuItem.getActionView();
+
+            mSearchView.setQueryHint(getText(R.string.search_language_hint));
+            mSearchView.setOnQueryTextListener(this);
+            mSearchView.setQuery("", false /* submit */);
         }
     }
+
+    @Override
+    public boolean onQueryTextSubmit(String query) {
+        return false;
+    }
+
+    @Override
+    public boolean onQueryTextChange(String newText) {
+        if (mAdapter != null) {
+            mAdapter.getFilter().filter(newText);
+        }
+        return false;
+    }
 }
diff --git a/core/java/com/android/internal/app/LocaleStore.java b/core/java/com/android/internal/app/LocaleStore.java
new file mode 100644
index 0000000..2191c58
--- /dev/null
+++ b/core/java/com/android/internal/app/LocaleStore.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.IllformedLocaleException;
+import java.util.Locale;
+import java.util.Set;
+
+public class LocaleStore {
+    private static final HashMap<String, LocaleInfo> sLocaleCache = new HashMap<>();
+    private static boolean sFullyInitialized = false;
+
+    public static class LocaleInfo {
+        private static final int SUGGESTION_TYPE_NONE = 0x00;
+        private static final int SUGGESTION_TYPE_SIM = 0x01;
+
+        private final Locale mLocale;
+        private final Locale mParent;
+        private final String mId;
+        private boolean mIsTranslated;
+        private boolean mIsPseudo;
+        private boolean mIsChecked; // Used by the LocaleListEditor to mark entries for deletion
+        // Combination of flags for various reasons to show a locale as a suggestion.
+        // Can be SIM, location, etc.
+        private int mSuggestionFlags;
+
+        private String mFullNameNative;
+        private String mFullCountryNameNative;
+        private String mLangScriptKey;
+
+        private LocaleInfo(Locale locale) {
+            this.mLocale = locale;
+            this.mId = locale.toLanguageTag();
+            this.mParent = getParent(locale);
+            this.mIsChecked = false;
+            this.mSuggestionFlags = SUGGESTION_TYPE_NONE;
+            this.mIsTranslated = false;
+            this.mIsPseudo = false;
+        }
+
+        private LocaleInfo(String localeId) {
+            this(Locale.forLanguageTag(localeId));
+        }
+
+        private static Locale getParent(Locale locale) {
+            if (locale.getCountry().isEmpty()) {
+                return null;
+            }
+            return new Locale.Builder()
+                    .setLocale(locale).setRegion("")
+                    .build();
+        }
+
+        @Override
+        public String toString() {
+            return mId;
+        }
+
+        public Locale getLocale() {
+            return mLocale;
+        }
+
+        public Locale getParent() {
+            return mParent;
+        }
+
+        public String getId() {
+            return mId;
+        }
+
+        public boolean isTranslated() {
+            return mIsTranslated;
+        }
+
+        public void setTranslated(boolean isTranslated) {
+            mIsTranslated = isTranslated;
+        }
+
+        /* package */ boolean isSuggested() {
+            if (!mIsTranslated) { // Never suggest an untranslated locale
+                return false;
+            }
+            return mSuggestionFlags != SUGGESTION_TYPE_NONE;
+        }
+
+        private boolean isSuggestionOfType(int suggestionMask) {
+            return (mSuggestionFlags & suggestionMask) == suggestionMask;
+        }
+
+        public String getFullNameNative() {
+            if (mFullNameNative == null) {
+                mFullNameNative =
+                        LocaleHelper.getDisplayName(mLocale, mLocale, true /* sentence case */);
+            }
+            return mFullNameNative;
+        }
+
+        String getFullCountryNameNative() {
+            if (mFullCountryNameNative == null) {
+                mFullCountryNameNative = LocaleHelper.getDisplayCountry(mLocale, mLocale);
+            }
+            return mFullCountryNameNative;
+        }
+
+        /** Returns the name of the locale in the language of the UI.
+         * It is used for search, but never shown.
+         * For instance German will show as "Deutsch" in the list, but we will also search for
+         * "allemand" if the system UI is in French.
+         */
+        public String getFullNameInUiLanguage() {
+            return LocaleHelper.getDisplayName(mLocale, true /* sentence case */);
+        }
+
+        private String getLangScriptKey() {
+            if (mLangScriptKey == null) {
+                Locale parentWithScript = getParent(LocaleHelper.addLikelySubtags(mLocale));
+                mLangScriptKey =
+                        (parentWithScript == null)
+                        ? mLocale.toLanguageTag()
+                        : parentWithScript.toLanguageTag();
+            }
+            return mLangScriptKey;
+        }
+
+        String getLabel() {
+            if (getParent() == null || this.isSuggestionOfType(SUGGESTION_TYPE_SIM)) {
+                return getFullNameNative();
+            } else {
+                return getFullCountryNameNative();
+            }
+        }
+
+        public boolean getChecked() {
+            return mIsChecked;
+        }
+
+        public void setChecked(boolean checked) {
+            mIsChecked = checked;
+        }
+    }
+
+    private static Set<String> getSimCountries(Context context) {
+        Set<String> result = new HashSet<>();
+
+        TelephonyManager tm = TelephonyManager.from(context);
+
+        if (tm != null) {
+            String iso = tm.getSimCountryIso().toUpperCase(Locale.US);
+            if (!iso.isEmpty()) {
+                result.add(iso);
+            }
+
+            iso = tm.getNetworkCountryIso().toUpperCase(Locale.US);
+            if (!iso.isEmpty()) {
+                result.add(iso);
+            }
+        }
+
+        return result;
+    }
+
+    public static void fillCache(Context context) {
+        if (sFullyInitialized) {
+            return;
+        }
+
+        Set<String> simCountries = getSimCountries(context);
+
+        for (String localeId : LocalePicker.getSupportedLocales(context)) {
+            if (localeId.isEmpty()) {
+                throw new IllformedLocaleException("Bad locale entry in locale_config.xml");
+            }
+            LocaleInfo li = new LocaleInfo(localeId);
+            if (simCountries.contains(li.getLocale().getCountry())) {
+                li.mSuggestionFlags |= LocaleInfo.SUGGESTION_TYPE_SIM;
+            }
+            sLocaleCache.put(li.getId(), li);
+            final Locale parent = li.getParent();
+            if (parent != null) {
+                String parentId = parent.toLanguageTag();
+                if (!sLocaleCache.containsKey(parentId)) {
+                    sLocaleCache.put(parentId, new LocaleInfo(parent));
+                }
+            }
+        }
+
+        boolean isInDeveloperMode = Settings.Global.getInt(context.getContentResolver(),
+                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
+        for (String localeId : LocalePicker.getPseudoLocales()) {
+            LocaleInfo li = getLocaleInfo(Locale.forLanguageTag(localeId));
+            if (isInDeveloperMode) {
+                li.setTranslated(true);
+                li.mIsPseudo = true;
+                li.mSuggestionFlags |= LocaleInfo.SUGGESTION_TYPE_SIM;
+            } else {
+                sLocaleCache.remove(li.getId());
+            }
+        }
+
+        // TODO: See if we can reuse what LocaleList.matchScore does
+        final HashSet<String> localizedLocales = new HashSet<>();
+        for (String localeId : LocalePicker.getSystemAssetLocales()) {
+            LocaleInfo li = new LocaleInfo(localeId);
+            localizedLocales.add(li.getLangScriptKey());
+        }
+
+        for (LocaleInfo li : sLocaleCache.values()) {
+            li.setTranslated(localizedLocales.contains(li.getLangScriptKey()));
+        }
+
+        sFullyInitialized = true;
+    }
+
+    private static int getLevel(Set<String> ignorables, LocaleInfo li, boolean translatedOnly) {
+        if (ignorables.contains(li.getId())) return 0;
+        if (li.mIsPseudo) return 2;
+        if (translatedOnly && !li.isTranslated()) return 0;
+        if (li.getParent() != null) return 2;
+        return 0;
+    }
+
+    /**
+     * Returns a list of locales for language or region selection.
+     * If the parent is null, then it is the language list.
+     * If it is not null, then the list will contain all the locales that belong to that perent.
+     * Example: if the parent is "ar", then the region list will contain all Arabic locales.
+     * (this is not language based, but language-script, so that it works for zh-Hant and so on.
+     */
+    /* package */ static Set<LocaleInfo> getLevelLocales(Context context, Set<String> ignorables,
+            LocaleInfo parent, boolean translatedOnly) {
+        fillCache(context);
+        String parentId = parent == null ? null : parent.getId();
+
+        HashSet<LocaleInfo> result = new HashSet<>();
+        for (LocaleStore.LocaleInfo li : sLocaleCache.values()) {
+            int level = getLevel(ignorables, li, translatedOnly);
+            if (level == 2) {
+                if (parent != null) { // region selection
+                    if (parentId.equals(li.getParent().toLanguageTag())) {
+                        if (!li.isSuggestionOfType(LocaleInfo.SUGGESTION_TYPE_SIM)) {
+                            result.add(li);
+                        }
+                    }
+                } else { // language selection
+                    if (li.isSuggestionOfType(LocaleInfo.SUGGESTION_TYPE_SIM)) {
+                        result.add(li);
+                    } else {
+                        result.add(getLocaleInfo(li.getParent()));
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    public static LocaleInfo getLocaleInfo(Locale locale) {
+        String id = locale.toLanguageTag();
+        LocaleInfo result;
+        if (!sLocaleCache.containsKey(id)) {
+            result = new LocaleInfo(locale);
+            sLocaleCache.put(id, result);
+        } else {
+            result = sLocaleCache.get(id);
+        }
+        return result;
+    }
+}
diff --git a/core/java/com/android/internal/app/SuggestedLocaleAdapter.java b/core/java/com/android/internal/app/SuggestedLocaleAdapter.java
new file mode 100644
index 0000000..2f855c6
--- /dev/null
+++ b/core/java/com/android/internal/app/SuggestedLocaleAdapter.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.Filter;
+import android.widget.Filterable;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.internal.R;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Locale;
+import java.util.Set;
+
+
+/**
+ * This adapter wraps around a regular ListAdapter for LocaleInfo, and creates 2 sections.
+ *
+ * <p>The first section contains "suggested" languages (usually including a region),
+ * the second section contains all the languages within the original adapter.
+ * The "others" might still include languages that appear in the "suggested" section.</p>
+ *
+ * <p>Example: if we show "German Switzerland" as "suggested" (based on SIM, let's say),
+ * then "German" will still show in the "others" section, clicking on it will only show the
+ * countries for all the other German locales, but not Switzerland
+ * (Austria, Belgium, Germany, Liechtenstein, Luxembourg)</p>
+ */
+class SuggestedLocaleAdapter extends BaseAdapter implements Filterable {
+    private static final int TYPE_HEADER_SUGGESTED = 0;
+    private static final int TYPE_HEADER_ALL_OTHERS = 1;
+    private static final int TYPE_LOCALE = 2;
+
+    private ArrayList<LocaleStore.LocaleInfo> mLocaleOptions;
+    private ArrayList<LocaleStore.LocaleInfo> mOriginalLocaleOptions;
+    private int mSuggestionCount;
+    private final boolean mCountryMode;
+    private LayoutInflater mInflater;
+
+    SuggestedLocaleAdapter(Set<LocaleStore.LocaleInfo> localeOptions, boolean countryMode) {
+        mCountryMode = countryMode;
+        mLocaleOptions = new ArrayList<>(localeOptions.size());
+        for (LocaleStore.LocaleInfo li : localeOptions) {
+            if (li.isSuggested()) {
+                mSuggestionCount++;
+            }
+            mLocaleOptions.add(li);
+        }
+    }
+
+    @Override
+    public boolean areAllItemsEnabled() {
+        return false;
+    }
+
+    @Override
+    public boolean isEnabled(int position) {
+        return getItemViewType(position) == TYPE_LOCALE;
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        if (!showHeaders()) {
+            return TYPE_LOCALE;
+        } else {
+            if (position == 0) {
+                return TYPE_HEADER_SUGGESTED;
+            }
+            if (position == mSuggestionCount + 1) {
+                return TYPE_HEADER_ALL_OTHERS;
+            }
+            return TYPE_LOCALE;
+        }
+    }
+
+    @Override
+    public int getViewTypeCount() {
+        if (showHeaders()) {
+            return 3; // Two headers in addition to the locales
+        } else {
+            return 1; // Locales items only
+        }
+    }
+
+    @Override
+    public int getCount() {
+        if (showHeaders()) {
+            return mLocaleOptions.size() + 2; // 2 extra for the headers
+        } else {
+            return mLocaleOptions.size();
+        }
+    }
+
+    @Override
+    public Object getItem(int position) {
+        int offset = 0;
+        if (showHeaders()) {
+            offset = position > mSuggestionCount ? -2 : -1;
+        }
+
+        return mLocaleOptions.get(position + offset);
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return position;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        if (convertView == null && mInflater == null) {
+            mInflater = LayoutInflater.from(parent.getContext());
+        }
+
+        int itemType = getItemViewType(position);
+        switch (itemType) {
+            case TYPE_HEADER_SUGGESTED: // intentional fallthrough
+            case TYPE_HEADER_ALL_OTHERS:
+                // Covers both null, and "reusing" a wrong kind of view
+                if (!(convertView instanceof TextView)) {
+                    convertView = mInflater.inflate(R.layout.language_picker_section_header,
+                            parent, false);
+                }
+                TextView textView = (TextView) convertView;
+                if (itemType == TYPE_HEADER_SUGGESTED) {
+                    textView.setText(R.string.language_picker_section_suggested);
+                } else {
+                    textView.setText(R.string.language_picker_section_all);
+                }
+                textView.setTextLocale(Locale.getDefault());
+                break;
+            default:
+                // Covers both null, and "reusing" a wrong kind of view
+                if (!(convertView instanceof ViewGroup)) {
+                    convertView = mInflater.inflate(R.layout.language_picker_item, parent, false);
+                }
+
+                TextView text = (TextView) convertView.findViewById(R.id.locale);
+                ImageView localized = (ImageView) convertView.findViewById(R.id.l10nWarn);
+                LocaleStore.LocaleInfo item = (LocaleStore.LocaleInfo) getItem(position);
+                text.setText(item.getLabel());
+                if (item.isTranslated() || mCountryMode) {
+                    localized.setVisibility(View.GONE);
+                    text.setTextLocale(item.getLocale());
+                } else {
+                    localized.setVisibility(View.VISIBLE);
+                    text.setTextLocale(Locale.getDefault());
+                }
+        }
+        return convertView;
+    }
+
+
+    private boolean showHeaders() {
+        return mSuggestionCount != 0 && mSuggestionCount != mLocaleOptions.size();
+    }
+
+    public void sort(LocaleHelper.LocaleInfoComparator comp) {
+        Collections.sort(mLocaleOptions, comp);
+    }
+
+    class FilterByNativeAndUiNames extends Filter {
+
+        @Override
+        protected FilterResults performFiltering(CharSequence prefix) {
+            FilterResults results = new FilterResults();
+
+            if (mOriginalLocaleOptions == null) {
+                mOriginalLocaleOptions = new ArrayList<>(mLocaleOptions);
+            }
+
+            ArrayList<LocaleStore.LocaleInfo> values;
+            values = new ArrayList<>(mOriginalLocaleOptions);
+            if (prefix == null || prefix.length() == 0) {
+                results.values = values;
+                results.count = values.size();
+            } else {
+                // TODO: decide if we should use the string's locale
+                Locale locale = Locale.getDefault();
+                String prefixString = LocaleHelper.normalizeForSearch(prefix.toString(), locale);
+
+                final int count = values.size();
+                final ArrayList<LocaleStore.LocaleInfo> newValues = new ArrayList<>();
+
+                for (int i = 0; i < count; i++) {
+                    final LocaleStore.LocaleInfo value = values.get(i);
+                    final String nameToCheck = LocaleHelper.normalizeForSearch(
+                            value.getFullNameInUiLanguage(), locale);
+                    final String nativeNameToCheck = LocaleHelper.normalizeForSearch(
+                            value.getFullNameNative(), locale);
+                    if (wordMatches(nativeNameToCheck, prefixString)
+                            || wordMatches(nameToCheck, prefixString)) {
+                        newValues.add(value);
+                    }
+                }
+
+                results.values = newValues;
+                results.count = newValues.size();
+            }
+
+            return results;
+        }
+
+        // TODO: decide if this is enough, or we want to use a BreakIterator...
+        boolean wordMatches(String valueText, String prefixString) {
+            // First match against the whole, non-splitted value
+            if (valueText.startsWith(prefixString)) {
+                return true;
+            }
+
+            final String[] words = valueText.split(" ");
+            // Start at index 0, in case valueText starts with space(s)
+            for (String word : words) {
+                if (word.startsWith(prefixString)) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        protected void publishResults(CharSequence constraint, FilterResults results) {
+            mLocaleOptions = (ArrayList<LocaleStore.LocaleInfo>) results.values;
+
+            mSuggestionCount = 0;
+            for (LocaleStore.LocaleInfo li : mLocaleOptions) {
+                if (li.isSuggested()) {
+                    mSuggestionCount++;
+                }
+            }
+
+            if (results.count > 0) {
+                notifyDataSetChanged();
+            } else {
+                notifyDataSetInvalidated();
+            }
+        }
+    }
+
+    @Override
+    public Filter getFilter() {
+        return new FilterByNativeAndUiNames();
+    }
+}
diff --git a/core/java/com/android/internal/backup/IBackupTransport.aidl b/core/java/com/android/internal/backup/IBackupTransport.aidl
index 083d6c7..b1fc20d 100644
--- a/core/java/com/android/internal/backup/IBackupTransport.aidl
+++ b/core/java/com/android/internal/backup/IBackupTransport.aidl
@@ -133,19 +133,16 @@
      *
      * @param packageInfo The identity of the application whose data is being backed up.
      *   This specifically includes the signature list for the package.
-     * @param data The data stream that resulted from invoking the application's
+     * @param inFd Descriptor of file with data that resulted from invoking the application's
      *   BackupService.doBackup() method.  This may be a pipe rather than a file on
      *   persistent media, so it may not be seekable.
-     * @param wipeAllFirst When true, <i>all</i> backed-up data for the current device/account
-     *   will be erased prior to the storage of the data provided here.  The purpose of this
-     *   is to provide a guarantee that no stale data exists in the restore set when the
-     *   device begins providing backups.
+     * @param flags Some of {@link BackupTransport#FLAG_USER_INITIATED}.
      * @return one of {@link BackupConstants#TRANSPORT_OK} (OK so far),
      *  {@link BackupConstants#TRANSPORT_ERROR} (on network error or other failure), or
      *  {@link BackupConstants#TRANSPORT_NOT_INITIALIZED} (if the backend dataset has
      *  become lost due to inactive expiry or some other reason and needs re-initializing)
      */
-    int performBackup(in PackageInfo packageInfo, in ParcelFileDescriptor inFd);
+    int performBackup(in PackageInfo packageInfo, in ParcelFileDescriptor inFd, int flags);
 
     /**
      * Erase the give application's data from the backup destination.  This clears
@@ -237,7 +234,7 @@
     // full backup stuff
 
     long requestFullBackupTime();
-    int performFullBackup(in PackageInfo targetPackage, in ParcelFileDescriptor socket);
+    int performFullBackup(in PackageInfo targetPackage, in ParcelFileDescriptor socket, int flags);
     int checkFullBackupSize(long size);
     int sendBackupData(int numBytes);
     void cancelFullBackup();
diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java
index 481ab0e..c0dce22 100644
--- a/core/java/com/android/internal/content/PackageMonitor.java
+++ b/core/java/com/android/internal/content/PackageMonitor.java
@@ -47,6 +47,8 @@
         sPackageFilt.addDataScheme("package");
         sNonDataFilt.addAction(Intent.ACTION_UID_REMOVED);
         sNonDataFilt.addAction(Intent.ACTION_USER_STOPPED);
+        sNonDataFilt.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
+        sNonDataFilt.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED);
         sExternalFilt.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
         sExternalFilt.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
     }
@@ -185,7 +187,13 @@
     
     public void onPackagesUnavailable(String[] packages) {
     }
-    
+
+    public void onPackagesSuspended(String[] packages) {
+    }
+
+    public void onPackagesUnsuspended(String[] packages) {
+    }
+
     public static final int PACKAGE_UNCHANGED = 0;
     public static final int PACKAGE_UPDATING = 1;
     public static final int PACKAGE_TEMPORARY_CHANGE = 2;
@@ -396,8 +404,16 @@
                     onPackageDisappeared(pkgList[i], mChangeType);
                 }
             }
+        } else if (Intent.ACTION_PACKAGES_SUSPENDED.equals(action)) {
+            String[] pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
+            mSomePackagesChanged = true;
+            onPackagesSuspended(pkgList);
+        } else if (Intent.ACTION_PACKAGES_UNSUSPENDED.equals(action)) {
+            String[] pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
+            mSomePackagesChanged = true;
+            onPackagesUnsuspended(pkgList);
         }
-        
+
         if (mSomePackagesChanged) {
             onSomePackagesChanged();
         }
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index cc815c4..57220b1 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -19,6 +19,7 @@
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.bluetooth.BluetoothActivityEnergyInfo;
+import android.bluetooth.UidTraffic;
 import android.content.Context;
 import android.content.Intent;
 import android.net.ConnectivityManager;
@@ -95,7 +96,7 @@
     private static final String TAG = "BatteryStatsImpl";
     private static final boolean DEBUG = false;
     public static final boolean DEBUG_ENERGY = false;
-    private static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY || false;
+    private static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY;
     private static final boolean DEBUG_HISTORY = false;
     private static final boolean USE_OLD_HISTORY = false;   // for debugging.
 
@@ -105,7 +106,7 @@
     private static final int MAGIC = 0xBA757475; // 'BATSTATS'
 
     // Current on-disk Parcel version
-    private static final int VERSION = 138 + (USE_OLD_HISTORY ? 1000 : 0);
+    private static final int VERSION = 139 + (USE_OLD_HISTORY ? 1000 : 0);
 
     // Maximum number of items we will record in the history.
     private static final int MAX_HISTORY_ITEMS = 2000;
@@ -196,8 +197,7 @@
     /**
      * The statistics we have collected organized by uids.
      */
-    final SparseArray<BatteryStatsImpl.Uid> mUidStats =
-        new SparseArray<BatteryStatsImpl.Uid>();
+    final SparseArray<BatteryStatsImpl.Uid> mUidStats = new SparseArray<>();
 
     // A set of pools of currently active timers.  When a timer is queried, we will divide the
     // elapsed time by the number of active timers to arrive at that timer's share of the time.
@@ -4691,6 +4691,13 @@
             mWifiControllerTime[type].addCountLocked(timeMs);
         }
 
+        public void noteBluetoothControllerActivityLocked(int type, long timeMs) {
+            if (mBluetoothControllerTime[type] == null) {
+                mBluetoothControllerTime[type] = new LongSamplingCounter(mOnBatteryTimeBase);
+            }
+            mBluetoothControllerTime[type].addCountLocked(timeMs);
+        }
+
         public StopwatchTimer createAudioTurnedOnTimerLocked() {
             if (mAudioTurnedOnTimer == null) {
                 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
@@ -5085,6 +5092,15 @@
             return 0;
         }
 
+        @Override
+        public long getBluetoothControllerActivity(int type, int which) {
+            if (type >= 0 && type < NUM_CONTROLLER_ACTIVITY_TYPES &&
+                    mBluetoothControllerTime[type] != null) {
+                return mBluetoothControllerTime[type].getCountLocked(which);
+            }
+            return 0;
+        }
+
         void initNetworkActivityLocked() {
             mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
             mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
@@ -7998,7 +8014,7 @@
      */
     public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) {
         if (DEBUG_ENERGY) {
-            Slog.d(TAG, "Updating bluetooth stats");
+            Slog.d(TAG, "Updating bluetooth stats: " + info);
         }
 
         if (info != null && mOnBatteryInternal) {
@@ -8018,6 +8034,23 @@
                 mBluetoothActivityCounters[CONTROLLER_POWER_DRAIN].addCountLocked(
                         (long) (info.getControllerEnergyUsed() / opVolt));
             }
+
+            final UidTraffic[] uidTraffic = info.getUidTraffic();
+            final int numUids = uidTraffic != null ? uidTraffic.length : 0;
+            for (int i = 0; i < numUids; i++) {
+                final UidTraffic traffic = uidTraffic[i];
+
+                // Add to the global counters.
+                mNetworkByteActivityCounters[NETWORK_BT_RX_DATA].addCountLocked(
+                        traffic.getRxBytes());
+                mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked(
+                        traffic.getTxBytes());
+
+                // Add to the UID counters.
+                final Uid u = getUidStatsLocked(mapUid(traffic.getUid()));
+                u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, traffic.getRxBytes(), 0);
+                u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, traffic.getTxBytes(), 0);
+            }
         }
     }
 
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 7ae0efb..36009dc 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -35,6 +35,7 @@
 import android.animation.ObjectAnimator;
 import android.app.ActivityManager;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -95,6 +96,8 @@
 public class DecorView extends FrameLayout implements RootViewSurfaceTaker, WindowCallbacks {
     private static final String TAG = "DecorView";
 
+    private static final boolean DEBUG_MEASURE = false;
+
     private static final boolean SWEEP_OPEN_MENU = false;
 
     // The height of a window which has focus in DIP.
@@ -575,7 +578,7 @@
                 } else {
                     w = 0;
                 }
-
+                if (DEBUG_MEASURE) Log.d(mLogTag, "Fixed width: " + w);
                 if (w > 0) {
                     final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
                     widthMeasureSpec = MeasureSpec.makeMeasureSpec(
@@ -597,6 +600,7 @@
                 } else {
                     h = 0;
                 }
+                if (DEBUG_MEASURE) Log.d(mLogTag, "Fixed height: " + h);
                 if (h > 0) {
                     final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
                     heightMeasureSpec = MeasureSpec.makeMeasureSpec(
@@ -641,6 +645,8 @@
                 } else {
                     min = 0;
                 }
+                if (DEBUG_MEASURE) Log.d(mLogTag, "Adjust for min width: " + min + ", value::"
+                        + tv.coerceToString() + ", mAvailableWidth=" + mAvailableWidth);
 
                 if (width < min) {
                     widthMeasureSpec = MeasureSpec.makeMeasureSpec(min, EXACTLY);
@@ -1591,7 +1597,9 @@
         }
     }
 
-    void onConfigurationChanged() {
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
         int workspaceId = getStackId();
         if (mStackId != workspaceId) {
             mStackId = workspaceId;
@@ -1948,13 +1956,22 @@
         }
     }
 
-    void updateLogTag(WindowManager.LayoutParams params) {
+    private static String getTitleSuffix(WindowManager.LayoutParams params) {
+        if (params == null) {
+            return "";
+        }
         final String[] split = params.getTitle().toString().split("\\.");
         if (split.length > 0) {
-            mLogTag = TAG + "[" + split[split.length - 1] + "]";
+            return split[split.length - 1];
+        } else {
+            return "";
         }
     }
 
+    void updateLogTag(WindowManager.LayoutParams params) {
+        mLogTag = TAG + "[" + getTitleSuffix(params) + "]";
+    }
+
     private void updateAvailableWidth() {
         Resources res = getResources();
         mAvailableWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
@@ -1976,6 +1993,12 @@
         }
     }
 
+    @Override
+    public String toString() {
+        return "DecorView@" + Integer.toHexString(this.hashCode()) + "["
+                + getTitleSuffix(mWindow.getAttributes()) + "]";
+    }
+
     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 4670cca..19ed11a 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -672,15 +672,12 @@
                 }
             }
         }
-        if (mDecor != null) {
-            mDecor.onConfigurationChanged();
-        }
     }
 
     @Override
     public void onMultiWindowModeChanged() {
         if (mDecor != null) {
-            mDecor.onConfigurationChanged();
+            mDecor.onConfigurationChanged(getContext().getResources().getConfiguration());
         }
     }
 
diff --git a/core/java/com/android/internal/widget/SubtitleView.java b/core/java/com/android/internal/widget/SubtitleView.java
index 8c395ec..3230185 100644
--- a/core/java/com/android/internal/widget/SubtitleView.java
+++ b/core/java/com/android/internal/widget/SubtitleView.java
@@ -28,6 +28,7 @@
 import android.graphics.RectF;
 import android.graphics.Typeface;
 import android.text.Layout.Alignment;
+import android.text.SpannableStringBuilder;
 import android.text.StaticLayout;
 import android.text.TextPaint;
 import android.util.AttributeSet;
@@ -54,8 +55,8 @@
     /** Temporary rectangle used for computing line bounds. */
     private final RectF mLineBounds = new RectF();
 
-    /** Reusable string builder used for holding text. */
-    private final StringBuilder mText = new StringBuilder();
+    /** Reusable spannable string builder used for holding text. */
+    private final SpannableStringBuilder mText = new SpannableStringBuilder();
 
     private Alignment mAlignment;
     private TextPaint mTextPaint;
@@ -141,7 +142,7 @@
     }
 
     public void setText(CharSequence text) {
-        mText.setLength(0);
+        mText.clear();
         mText.append(text);
 
         mHasMeasurements = false;
diff --git a/core/java/com/android/server/backup/AccountSyncSettingsBackupHelper.java b/core/java/com/android/server/backup/AccountSyncSettingsBackupHelper.java
index c0215a8..0449340 100644
--- a/core/java/com/android/server/backup/AccountSyncSettingsBackupHelper.java
+++ b/core/java/com/android/server/backup/AccountSyncSettingsBackupHelper.java
@@ -203,9 +203,8 @@
             }
         } catch (EOFException eof) {
             // Initial state may be empty.
-        } finally {
-            dataInput.close();
         }
+        // We explicitly don't close 'dataInput' because we must not close the backing fd.
         return oldMd5Checksum;
     }
 
@@ -219,7 +218,10 @@
 
         dataOutput.writeInt(STATE_VERSION);
         dataOutput.write(md5Checksum);
-        dataOutput.close();
+
+        // We explicitly don't close 'dataOutput' because we must not close the backing fd.
+        // The FileOutputStream will not close it implicitly.
+
     }
 
     private byte[] generateMd5Checksum(byte[] data) throws NoSuchAlgorithmException {
diff --git a/core/java/org/apache/http/conn/ssl/AbstractVerifier.java b/core/java/org/apache/http/conn/ssl/AbstractVerifier.java
index 66a5121..b9349b39 100644
--- a/core/java/org/apache/http/conn/ssl/AbstractVerifier.java
+++ b/core/java/org/apache/http/conn/ssl/AbstractVerifier.java
@@ -208,8 +208,8 @@
     }
 
     public static String[] getCNs(X509Certificate cert) {
-        DistinguishedNameParser dnParser =
-                new DistinguishedNameParser(cert.getSubjectX500Principal());
+        AndroidDistinguishedNameParser dnParser =
+                new AndroidDistinguishedNameParser(cert.getSubjectX500Principal());
         List<String> cnList = dnParser.getAllMostSpecificFirst("cn");
 
         if(!cnList.isEmpty()) {
diff --git a/core/java/org/apache/http/conn/ssl/DistinguishedNameParser.java b/core/java/org/apache/http/conn/ssl/AndroidDistinguishedNameParser.java
similarity index 99%
rename from core/java/org/apache/http/conn/ssl/DistinguishedNameParser.java
rename to core/java/org/apache/http/conn/ssl/AndroidDistinguishedNameParser.java
index b2d0e3e..4f0b726 100644
--- a/core/java/org/apache/http/conn/ssl/DistinguishedNameParser.java
+++ b/core/java/org/apache/http/conn/ssl/AndroidDistinguishedNameParser.java
@@ -29,7 +29,7 @@
  * @hide
  */
 @Deprecated
-final class DistinguishedNameParser {
+final class AndroidDistinguishedNameParser {
     private final String dn;
     private final int length;
     private int pos;
@@ -42,7 +42,7 @@
     /** distinguished name chars */
     private char[] chars;
 
-    public DistinguishedNameParser(X500Principal principal) {
+    public AndroidDistinguishedNameParser(X500Principal principal) {
         // RFC2253 is used to ensure we get attributes in the reverse
         // order of the underlying ASN.1 encoding, so that the most
         // significant values of repeated attributes occur first.
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index a79183d..644ecc6 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -7,6 +7,7 @@
 LOCAL_CFLAGS += -Wno-unused-parameter
 LOCAL_CFLAGS += -Wno-non-virtual-dtor
 LOCAL_CFLAGS += -Wno-maybe-uninitialized -Wno-parentheses
+LOCAL_CFLAGS += -DHWUI_NEW_OPS
 LOCAL_CPPFLAGS += -Wno-conversion-null
 
 ifeq ($(TARGET_ARCH), arm)
diff --git a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
index 70134ab..9fa90ac 100644
--- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
+++ b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
@@ -43,6 +43,7 @@
     jfieldID uid;
     jfieldID set;
     jfieldID tag;
+    jfieldID roaming;
     jfieldID rxBytes;
     jfieldID rxPackets;
     jfieldID txBytes;
@@ -238,6 +239,9 @@
     ScopedIntArrayRW tag(env, get_int_array(env, stats,
             gNetworkStatsClassInfo.tag, size, grow));
     if (tag.get() == NULL) return -1;
+    ScopedIntArrayRW roaming(env, get_int_array(env, stats,
+            gNetworkStatsClassInfo.roaming, size, grow));
+    if (roaming.get() == NULL) return -1;
     ScopedLongArrayRW rxBytes(env, get_long_array(env, stats,
             gNetworkStatsClassInfo.rxBytes, size, grow));
     if (rxBytes.get() == NULL) return -1;
@@ -261,6 +265,7 @@
         uid[i] = lines[i].uid;
         set[i] = lines[i].set;
         tag[i] = lines[i].tag;
+        // Roaming is populated in Java-land by inspecting the iface properties.
         rxBytes[i] = lines[i].rxBytes;
         rxPackets[i] = lines[i].rxPackets;
         txBytes[i] = lines[i].txBytes;
@@ -274,6 +279,7 @@
         env->SetObjectField(stats, gNetworkStatsClassInfo.uid, uid.getJavaArray());
         env->SetObjectField(stats, gNetworkStatsClassInfo.set, set.getJavaArray());
         env->SetObjectField(stats, gNetworkStatsClassInfo.tag, tag.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.roaming, roaming.getJavaArray());
         env->SetObjectField(stats, gNetworkStatsClassInfo.rxBytes, rxBytes.getJavaArray());
         env->SetObjectField(stats, gNetworkStatsClassInfo.rxPackets, rxPackets.getJavaArray());
         env->SetObjectField(stats, gNetworkStatsClassInfo.txBytes, txBytes.getJavaArray());
@@ -305,6 +311,7 @@
     gNetworkStatsClassInfo.uid = GetFieldIDOrDie(env, clazz, "uid", "[I");
     gNetworkStatsClassInfo.set = GetFieldIDOrDie(env, clazz, "set", "[I");
     gNetworkStatsClassInfo.tag = GetFieldIDOrDie(env, clazz, "tag", "[I");
+    gNetworkStatsClassInfo.roaming = GetFieldIDOrDie(env, clazz, "roaming", "[I");
     gNetworkStatsClassInfo.rxBytes = GetFieldIDOrDie(env, clazz, "rxBytes", "[J");
     gNetworkStatsClassInfo.rxPackets = GetFieldIDOrDie(env, clazz, "rxPackets", "[J");
     gNetworkStatsClassInfo.txBytes = GetFieldIDOrDie(env, clazz, "txBytes", "[J");
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index a277568..a82bfbe 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -47,6 +47,8 @@
     <protected-broadcast android:name="android.intent.action.PACKAGE_FIRST_LAUNCH" />
     <protected-broadcast android:name="android.intent.action.PACKAGE_NEEDS_VERIFICATION" />
     <protected-broadcast android:name="android.intent.action.PACKAGE_VERIFIED" />
+    <protected-broadcast android:name="android.intent.action.PACKAGES_SUSPENDED" />
+    <protected-broadcast android:name="android.intent.action.PACKAGES_UNSUSPENDED" />
     <protected-broadcast android:name="android.intent.action.UID_REMOVED" />
     <protected-broadcast android:name="android.intent.action.QUERY_PACKAGE_RESTART" />
     <protected-broadcast android:name="android.intent.action.CONFIGURATION_CHANGED" />
@@ -354,6 +356,20 @@
     <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.app.action.CHOOSE_PRIVATE_KEY_ALIAS" />
+    <protected-broadcast android:name="android.app.action.DEVICE_ADMIN_DISABLED" />
+    <protected-broadcast android:name="android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED" />
+    <protected-broadcast android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+    <protected-broadcast android:name="android.app.action.LOCK_TASK_ENTERING" />
+    <protected-broadcast android:name="android.app.action.LOCK_TASK_EXITING" />
+    <protected-broadcast android:name="android.app.action.NOTIFY_PENDING_SYSTEM_UPDATE" />
+    <protected-broadcast android:name="android.app.action.ACTION_PASSWORD_CHANGED" />
+    <protected-broadcast android:name="android.app.action.ACTION_PASSWORD_EXPIRING" />
+    <protected-broadcast android:name="android.app.action.ACTION_PASSWORD_FAILED" />
+    <protected-broadcast android:name="android.app.action.ACTION_PASSWORD_SUCCEEDED" />
+    <protected-broadcast android:name="com.android.server.ACTION_EXPIRED_PASSWORD_NOTIFICATION" />
+    <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_ADDED" />
+
     <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" />
diff --git a/core/res/res/layout-sw600dp/date_picker_dialog.xml b/core/res/res/layout-sw600dp/date_picker_dialog.xml
index f9b247f..f18485f 100644
--- a/core/res/res/layout-sw600dp/date_picker_dialog.xml
+++ b/core/res/res/layout-sw600dp/date_picker_dialog.xml
@@ -1,20 +1,18 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+     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.
 -->
 
 <DatePicker xmlns:android="http://schemas.android.com/apk/res/android"
@@ -23,5 +21,4 @@
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:spinnersShown="true"
-    android:calendarViewShown="true"
-    />
+    android:calendarViewShown="true" />
diff --git a/core/res/res/layout/date_picker_dialog.xml b/core/res/res/layout/date_picker_dialog.xml
index db8f311..64ac1b9 100644
--- a/core/res/res/layout/date_picker_dialog.xml
+++ b/core/res/res/layout/date_picker_dialog.xml
@@ -1,20 +1,18 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+     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.
 -->
 
 <DatePicker xmlns:android="http://schemas.android.com/apk/res/android"
@@ -23,5 +21,4 @@
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:spinnersShown="true"
-    android:calendarViewShown="false"
-    />
+    android:calendarViewShown="false" />
diff --git a/core/res/res/layout/date_picker_header_material.xml b/core/res/res/layout/date_picker_header_material.xml
index 821b588..cfc6d0d 100644
--- a/core/res/res/layout/date_picker_header_material.xml
+++ b/core/res/res/layout/date_picker_header_material.xml
@@ -19,35 +19,46 @@
               android:id="@+id/date_picker_header"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
-              android:paddingStart="?attr/dialogPreferredPadding"
-              android:paddingEnd="?attr/dialogPreferredPadding"
-              android:paddingTop="16dp"
-              android:paddingBottom="18dp"
-              android:orientation="vertical"
-              android:clipToPadding="false"
-              android:clipChildren="false">
+              android:orientation="vertical">
 
-    <TextView
-        android:id="@+id/date_picker_header_year"
-        android:layout_width="wrap_content"
+    <ViewStub
+        android:id="@id/topPanel"
+        android:layout="@layout/alert_dialog_title_material"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:focusable="true"
-        android:layout_marginStart="-8dp"
-        android:layout_marginEnd="-8dp"
-        android:layout_marginTop="-8dp"
-        android:layout_marginBottom="-8dp"
-        android:padding="8dp"
-        android:background="?attr/selectableItemBackground"
-        android:textAppearance="@style/TextAppearance.Material.DatePicker.YearLabel"
-        android:nextFocusForward="@+id/prev" />
+        android:paddingStart="?attr/dialogPreferredPadding"
+        android:paddingEnd="?attr/dialogPreferredPadding"
+        android:paddingTop="16dp"
+        android:paddingBottom="18dp"
+        android:orientation="vertical"
+        android:clipToPadding="false"
+        android:clipChildren="false">
 
-    <TextView
-        android:id="@+id/date_picker_header_date"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:textAppearance="@style/TextAppearance.Material.DatePicker.DateLabel"
-        android:gravity="start"
-        android:maxLines="2"
-        android:ellipsize="none" />
+        <TextView
+            android:id="@+id/date_picker_header_year"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:focusable="true"
+            android:layout_marginStart="-8dp"
+            android:layout_marginEnd="-8dp"
+            android:layout_marginTop="-8dp"
+            android:layout_marginBottom="-8dp"
+            android:padding="8dp"
+            android:background="?attr/selectableItemBackground"
+            android:textAppearance="@style/TextAppearance.Material.DatePicker.YearLabel"
+            android:nextFocusForward="@+id/prev" />
 
+        <TextView
+            android:id="@+id/date_picker_header_date"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="@style/TextAppearance.Material.DatePicker.DateLabel"
+            android:gravity="start"
+            android:maxLines="2"
+            android:ellipsize="none" />
+    </LinearLayout>
 </LinearLayout>
diff --git a/core/res/res/layout/input_method_switch_dialog_title.xml b/core/res/res/layout/input_method_switch_dialog_title.xml
index 856a7af..48fd5e6 100644
--- a/core/res/res/layout/input_method_switch_dialog_title.xml
+++ b/core/res/res/layout/input_method_switch_dialog_title.xml
@@ -70,24 +70,24 @@
                 android:orientation="vertical"
                 android:paddingBottom="5dp"
                 android:paddingStart="?attr/listPreferredItemPaddingStart"
-                android:paddingEnd="0dp"
-                android:paddingTop="5dp" >
+                android:paddingEnd="16dp"
+                android:paddingTop="16dp" >
 
                 <TextView
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:singleLine="true"
                     android:text="@string/hardware"
-                    android:textAppearance="?attr/textAppearanceMedium"
-                    android:textColor="?attr/textColorAlertDialogListItem" />
+                    android:textAppearance="?attr/textAppearanceListItem"
+                    android:ellipsize="marquee" />
 
                 <TextView
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:singleLine="true"
+                    android:maxLines="10"
                     android:text="@string/show_ime"
-                    android:textAppearance="?attr/textAppearanceSmall"
-                    android:textColor="?attr/textColorAlertDialogListItem" />
+                    android:textAppearance="?attr/textAppearanceListItemSecondary"
+                    android:textColor="?attr/textColorSecondary" />
             </LinearLayout>
 
             <Switch
diff --git a/core/res/res/layout/language_picker_item.xml b/core/res/res/layout/language_picker_item.xml
new file mode 100644
index 0000000..22cb514
--- /dev/null
+++ b/core/res/res/layout/language_picker_item.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              xmlns:tools="http://schemas.android.com/tools"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:gravity="center_vertical"
+              android:orientation="horizontal"
+              android:layoutDirection="locale"
+              android:textDirection="locale"
+              android:paddingBottom="8dp"
+              android:paddingTop="8dp">
+
+    <TextView
+        android:id="@+id/locale"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        tools:text="France"
+        android:layout_weight="1"
+        android:padding="12dp"
+        android:paddingStart="18dp"
+        android:paddingEnd="18dp"
+        android:textAppearance="?android:attr/textAppearanceListItem"/>
+
+    <ImageView
+        android:id="@+id/l10nWarn"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@android:drawable/stat_sys_warning"
+        android:focusableInTouchMode="false"
+        android:focusable="false"
+        android:paddingStart="12dp"
+        android:paddingEnd="12dp"
+        android:tint="?android:attr/colorAccent"/>
+
+</LinearLayout>
diff --git a/core/res/res/layout/language_picker_section_header.xml b/core/res/res/layout/language_picker_section_header.xml
new file mode 100644
index 0000000..c4d3069
--- /dev/null
+++ b/core/res/res/layout/language_picker_section_header.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+          xmlns:tools="http://schemas.android.com/tools"
+          style="?android:attr/preferenceCategoryStyle"
+          android:layout_width="match_parent"
+          android:layout_height="36dp"
+          android:paddingStart="12dp"
+          android:paddingEnd="12dp"
+          android:textColor="?android:attr/colorAccent"
+          tools:text="@string/language_picker_section_all"/>
diff --git a/core/res/res/layout/text_edit_suggestion_container.xml b/core/res/res/layout/text_edit_suggestion_container.xml
index 04eca8f..fe02d4e 100644
--- a/core/res/res/layout/text_edit_suggestion_container.xml
+++ b/core/res/res/layout/text_edit_suggestion_container.xml
@@ -16,6 +16,8 @@
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
+    android:background="@drawable/text_edit_suggestions_window"
+    android:dropDownSelector="@drawable/list_selector_background"
     android:divider="@null">
     <ListView
         android:id="@+id/suggestionContainer"
diff --git a/core/res/res/layout/text_edit_suggestion_container_material.xml b/core/res/res/layout/text_edit_suggestion_container_material.xml
index d0e2467..62e315b4 100644
--- a/core/res/res/layout/text_edit_suggestion_container_material.xml
+++ b/core/res/res/layout/text_edit_suggestion_container_material.xml
@@ -14,17 +14,19 @@
      limitations under the License.
 -->
 
+<!-- Background of the popup window is the same as the one of the floating toolbar.
+     Use floating toolbar background style. -->
 <LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
-    android:divider="?android:attr/dividerHorizontal"
+    android:background="?android:attr/floatingToolbarPopupBackgroundDrawable"
+    android:divider="?android:attr/listDivider"
     android:showDividers="middle" >
     <ListView
         android:id="@+id/suggestionContainer"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:background="@color/white"
         android:paddingTop="8dip"
-        android:paddingBottom="8dip"
+        android:paddingBottom="0dip"
         android:divider="@null" />
     <LinearLayout
         android:layout_width="match_parent"
diff --git a/core/res/res/menu/language_selection_list.xml b/core/res/res/menu/language_selection_list.xml
new file mode 100644
index 0000000..63b9627
--- /dev/null
+++ b/core/res/res/menu/language_selection_list.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+      xmlns:app="http://schemas.android.com/apk/res-auto">
+    <item
+        android:id="@+id/locale_search_menu"
+        android:title="@string/locale_search_menu"
+        app:showAsAction="always"
+        app:actionViewClass="android.widget.SearchView" />
+
+</menu>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 7916012..463ee0a 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Foutverslag"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Neem foutverslag"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Dit sal inligting oor die huidige toestand van jou toestel insamel om as \'n e-posboodskap te stuur. Dit sal \'n tydjie neem vandat die foutverslag begin is totdat dit reg is om gestuur te word; wees asseblief geduldig."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Stilmodus"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Klank is AF"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Klank is AAN"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Raak vir meer opsies."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-ontfouter gekoppel"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Raak om USB-ontfouting te deaktiveer."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Deel foutverslag met administrateur?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Jou IT-administrateur het \'n foutverslag versoek om met foutsporing te help"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"AANVAAR"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"WEIER"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Neem tans foutverslag …"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Raak om te kanselleer"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Verander sleutelbord"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Kies sleutelborde"</string>
     <string name="show_ime" msgid="9157568568695230830">"Wys invoermetode"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index be717f8..a4b502c 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"የሳንካ ሪፖርት"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"የሳንካ ሪፖርት ውሰድ"</string>
     <string name="bugreport_message" msgid="398447048750350456">"ይሄ እንደ የኢሜይል መልዕክት አድርጎ የሚልከውን ስለመሣሪያዎ የአሁኑ ሁኔታ መረጃ ይሰበስባል። የሳንካ ሪፖርቱን ከመጀመር ጀምሮ እስኪላክ ድረስ ትንሽ ጊዜ ይወስዳል፤ እባክዎ ይታገሱ።"</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"የፀጥታ ሁነታ"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ድምፅ ጠፍቷል"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ድምፅ በርቷል"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"ለተጨማሪ አማራጮች ነካ ያድርጉ።"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB አድስ ተያይዟል"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ማረሚያ ላለማንቃት ዳስስ።"</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"የሳንካ ሪፖርት ለአስተዳዳሪ ይጋራ?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"የእርስዎ የአይቲ አስተዳዳሪ መላ መፈለግ ላይ እንዲያግዝ የሳንካ ሪፖርት ጠይቀዋል"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ተቀበል"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ውድቅ አድርግ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"የሳንካ ሪፖርትን በመውሰድ ላይ…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"ለመሰረዝ ይንኩ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"ቁልፍ ሰሌዳ ይቀይሩ"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"ቁልፍ ሰሌዳዎችን ምረጥ"</string>
     <string name="show_ime" msgid="9157568568695230830">"የግቤት ስልት አሳይ"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"የተለያዩ"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"የእነዚህን ማሳወቂያዎች አስፈላጊነት አዘጋጅተዋል።"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"ይሄ በሚሳተፉ ሰዎች ምክንያት አስፈላጊ ነው።"</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" አዲስ ተጠቃሚ ለማከል እየሞከረ ነው፣ ነገር ግን አሁን ላይ ተከልክሏል።"</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" አዲስ ተጠቃሚ ለማከል እየሞከረ ነው፣ ሆኖም ግን የተጠቃሚ ብዛት ገደብ ላይ ተደርሷል።"</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" አዲስ ተጠቃሚ ለማከል እየሞከረ ነው፣ ነገር ግን መለያ "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" አስቀድሞ በዚህ መሣሪያ ላይ አለ። የሆነው ሆኖ ይቀጥል?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ለ"<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" መለያ አዲስ ተጠቃሚ ለማከል እየሞከረ ነው። ይቀጥል?"</string>
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 2545e66..ae22ede 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -215,6 +215,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"تقرير الأخطاء"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"إعداد تقرير بالأخطاء"</string>
     <string name="bugreport_message" msgid="398447048750350456">"سيجمع هذا معلومات حول حالة جهازك الحالي لإرسالها كرسالة إلكترونية، ولكنه سيستغرق وقتًا قليلاً من بدء عرض تقرير بالأخطاء. وحتى يكون جاهزًا للإرسال، الرجاء الانتظار."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"وضع صامت"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"الصوت متوقف"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"الصوت قيد التشغيل"</string>
@@ -1060,18 +1069,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"المس للحصول على مزيد من الخيارات."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏تم توصيل تصحيح أخطاء USB"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"‏المس لتعطيل تصحيح أخطاء USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"هل تريد مشاركة تقرير الأخطاء مع المشرف؟"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"طلب مشرف تكنولوجيا المعلومات الحصول على تقرير بالأخطاء للمساعدة في تحري الخلل وإصلاحه"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"قبول"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"رفض"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"جارٍ الحصول على تقرير بالأخطاء…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"المس للإلغاء"</string>
     <string name="select_input_method" msgid="8547250819326693584">"تغيير لوحة المفاتيح"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"اختيار لوحات المفاتيح"</string>
     <string name="show_ime" msgid="9157568568695230830">"إظهار طريقة الإدخال"</string>
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index c05aa59..b38d303 100644
--- a/core/res/res/values-az-rAZ/strings.xml
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Baq hesabatı"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Baqı xəbər verin"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Bu, sizin hazırkı cihaz durumu haqqında məlumat toplayacaq ki, elektron məktub şəklində göndərsin. Baq raportuna başlamaq üçün bir az vaxt lazım ola bilər, bir az səbr edin."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Səssiz rejim"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Səs qapalıdır"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Səs Aktivdir"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Əlavə seçimlər üçün toxunun."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB sazlama qoşuludur"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB debaqı deaktivasiya etmək üçün toxunun."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Baq hesabatı admin ilə paylaşılsın?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IT admininiz nasazlıqların aşkarlanması üçün baq hesabatı sorğusu göndərdi"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"QƏBUL EDİN"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"RƏDD ET"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Baq xəbər verilir..."</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Ləğv etmək üçün toxunun"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Klaviaturanı dəyişin"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Klaviaturaları seçin"</string>
     <string name="show_ime" msgid="9157568568695230830">"Daxiletmə metodunu göstərin"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 263a6a8..e69dd9a 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -212,6 +212,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Izveštaj o grešci"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Napravi izveštaj o grešci"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Ovim će se prikupiti informacije o trenutnom stanju uređaja kako bi bile poslate u poruci e-pošte. Od započinjanja izveštaja o grešci do trenutka za njegovo slanje proći će neko vreme; budite strpljivi."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Nečujni režim"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Zvuk je ISKLJUČEN"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Zvuk je UKLJUČEN"</string>
@@ -1039,18 +1048,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Dodirnite za još opcija."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Otklanjanje grešaka sa USB-a je uspostavljeno"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Dodirnite da biste onemogućili otklanjanje grešaka sa USB-a."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Želite li da delite izveštaj o grešci sa administratorom?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IT administrator je zatražio izveštaj o grešci radi lakšeg rešavanja problema"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"PRIHVATI"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ODBIJ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Izveštaj o grešci se generiše…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Dodirnite da biste otkazali"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Promenite tastaturu"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Izaberite tastature"</string>
     <string name="show_ime" msgid="9157568568695230830">"Prikazivanje metoda unosa"</string>
@@ -1542,12 +1545,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Razno"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Vi podešavate važnost ovih obaveštenja."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Ovo je važno zbog ljudi koji učestvuju."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" pokušava da doda novog korisnika, ali to je trenutno zabranjeno."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" pokušava da doda novog korisnika, ali je ograničenje za broj korisnika dostignuto."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" pokušava da doda novog korisnika, ali nalog "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" već postoji na ovom uređaju. Želite li ipak da nastavite?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" pokušava da doda novog korisnika za nalog "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Želite li da nastavite?"</string>
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 9c65b14..d15a738 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Сигнал за програмна грешка"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Сигнал за програмна грешка"</string>
     <string name="bugreport_message" msgid="398447048750350456">"По този начин ще се събере информация за текущото състояние на устройството ви, която да се изпрати като имейл съобщение. След стартирането на процеса ще мине известно време, докато сигналът за програмна грешка бъде готов за подаване. Моля, имайте търпение."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Тих режим"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Звукът е ИЗКЛЮЧЕН"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Звукът е ВКЛЮЧЕН"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Докоснете за още опции."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отстраняване на грешки през USB"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Докоснете за деактивиране"</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Да се сподели ли сигналът за програмна грешка с администратора?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Системният ви администратор заяви сигнал за програмна грешка с цел отстраняване на неизправностите"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ПРИЕМАМ"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ОТХВЪРЛЯМ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Сигналът за програмна грешка се извлича…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Докоснете, за да анулирате"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Промяна на клавиатурата"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Избиране на клавиатури"</string>
     <string name="show_ime" msgid="9157568568695230830">"Метод на въвежд.: Показв."</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Други"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Зададохте важността на тези известия."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Това е важно заради участващите хора."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" опитва да добави нов потребител, но понастоящем това е забранено."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" опитва да добави нов потребител, но ограничението за брой потребители е достигнато."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" опитва да добави нов потребител, но профилът "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" вече съществува на устройството. Да се продължи ли въпреки това?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" опитва да добави нов потребител за профила "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Да се продължи ли?"</string>
 </resources>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index a4bd29d..bb267f3 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"ত্রুটির প্রতিবেদন"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"ত্রুটির প্রতিবেদন করুন"</string>
     <string name="bugreport_message" msgid="398447048750350456">"এটি একটি ই-মেল বার্তা পাঠানোর জন্য আপনার ডিভাইসের বর্তমান অবস্থা সম্পর্কে তথ্য সংগ্রহ করবে৷ ত্রুটির প্রতিবেদন শুরুর সময় থেকে এটি পাঠানোর জন্য প্রস্তুত হতে কিছুটা সময় নেবে; দয়া করে ধৈর্য রাখুন৷"</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"নীরব মোড"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"শব্দ বন্ধ করা আছে"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"শব্দ চালু করা আছে"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"আরো বিকল্পের জন্য স্পর্শ করুন৷"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ডিবাগিং সংযুক্ত হয়েছে"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ডিবাগিং অক্ষম করতে স্পর্শ করুন৷"</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"প্রশাসকের সাথে ত্রুটির প্রতিবেদন ভাগ করবেন?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"আপনার IT প্রশাসক সমস্যা নিবারণে সহায়তা করতে একটি ত্রুটির প্রতিবেদন চেয়েছেন"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"স্বীকার করুন"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"অস্বীকার করুন"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"ত্রুটির প্রতিবেদন নেওয়া হচ্ছে..."</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"বাতিল করতে স্পর্শ করুন"</string>
     <string name="select_input_method" msgid="8547250819326693584">"কীবোর্ড পরিবর্তন করুন"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"কীবোর্ড চয়ন করুন"</string>
     <string name="show_ime" msgid="9157568568695230830">"ইনপুট পদ্ধতি দেখান"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"বিবিধ"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"আপনি এই বিজ্ঞপ্তিগুলির গুরুত্ব সেট করেছেন।"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"লোকজন জড়িত থাকার কারণে এটি গুরুত্বপূর্ণ।"</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" একজন নতুন ব্যবহারকারীকে যোগ করার চেষ্টা করছে, তবে বর্তমানে তা নিষিদ্ধ।"</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" একজন নতুন ব্যবহারকারী যোগ করার চেষ্টা করছে, তবে ব্যবহারকারীর সীমা অতিক্রান্ত হয়েছে।"</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" একজন নতুন ব্যবহারকারীকে যোগ করার চেষ্টা করছে, তবে "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" অ্যাকাউন্ট আগে থেকেই এই ডিভাইসটিতে বিদ্যমান আছে। তবুও এগোতে চান?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" অ্যাকাউন্টের জন্য একজন নতুন ব্যবহারকারীকে যোগ করার চেষ্টা করছে। এগোতে চান?"</string>
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index cd5ec4a..ba52781 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Informe d\'error"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Crea informe d\'errors"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Es recopilarà informació sobre l\'estat actual del dispositiu i se t\'enviarà per correu electrònic. Passaran uns quants minuts des de l\'inici de l\'informe d\'errors fins al seu enviament, per la qual cosa et recomanem que tinguis paciència."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mode silenciós"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"So desactivat"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"El so està activat"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Toca per veure més opcions."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuració USB activada"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca per desactivar la depuració USB"</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Vols compartir l\'informe d\'errors amb l\'administrador?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"El teu administrador de TI ha sol·licitat un informe d\'errors per tal de resoldre problemes"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACCEPTA"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"REBUTJA"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"S\'està creant l\'informe d\'errors…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Toca per cancel·lar"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Canvia el teclat"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Tria els teclats"</string>
     <string name="show_ime" msgid="9157568568695230830">"Mostra mètode d\'introducció"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Altres"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Tu has definit la importància d\'aquestes notificacions."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Aquest missatge és important per les persones implicades."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" està provant d\'afegir un usuari, però actualment aquesta acció no està permesa."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" està provant d\'afegir un usuari, però s\'ha assolit el límit d\'usuaris."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" està provant d\'afegir un usuari, però el compte "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ja existeix en aquest dispositiu. Vols continuar igualment?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" està provant d\'afegir un usuari per al compte "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Vols continuar?"</string>
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 9b7392b..1a73069 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -213,6 +213,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Hlášení chyb"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Vytvořit chybové hlášení"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Shromažďuje informace o aktuálním stavu zařízení. Tyto informace je následně možné poslat v e-mailové zprávě, chvíli však potrvá, než bude hlášení o chybě připraveno k odeslání. Buďte prosím trpěliví."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Tichý režim"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Zvuk je VYPNUTÝ."</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Zvuk je zapnutý"</string>
@@ -1046,18 +1055,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Klepnutím zobrazíte další možnosti."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Ladění přes USB připojeno"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Dotykem zakážete ladění USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Sdílet zprávu o chybě s administrátorem?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Administrátor IT si vyžádal zprávu o chybě, aby mohl problém odstranit."</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"PŘIJMOUT"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ODMÍTNOUT"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Vytváření zprávy o chybě…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Klepnutím zrušíte"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Změna klávesnice"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Vybrat klávesnici"</string>
     <string name="show_ime" msgid="9157568568695230830">"Zobrazit metodu zadávání"</string>
@@ -1560,12 +1563,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Různé"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Důležitost oznámení určujete vy."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Tato zpráva je důležitá kvůli lidem zapojeným do konverzace."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315">"Aplikace "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" se pokouší přidat nového uživatele, avšak v tuto chvíli je zakázána."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266">"Aplikace "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" se pokouší přidat nového uživatele, avšak byl dosažen maximální počet uživatelů."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789">"Aplikace "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" se pokouší přidat nového uživatele, avšak účet "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" již v zařízení existuje. Chcete přesto pokračovat?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392">"Aplikace "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" se pro účet "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" pokouší přidat nového uživatele. Pokračovat?"</string>
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index c83bfda..791a379 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Fejlrapport"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Lav fejlrapport"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Der indsamles oplysninger om din enheds aktuelle status, der efterfølgende sendes i en e-mail. Der går lidt tid, fra fejlrapporten påbegyndes, til den er klar til at blive sendt. Tak for tålmodigheden."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Lydløs"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Lyden er slået FRA"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Lyden er TIL"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Tryk for at se flere muligheder."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-fejlretning er tilsluttet"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Tryk for at deaktivere USB-fejlretning."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Vil du dele fejlrapporten med administratoren?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Din it-administrator har anmodet om en fejlrapport for bedre at kunne finde og rette fejlen"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACCEPTÉR"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"AFVIS"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Opretter fejlrapport…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Tryk for at annullere"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Skift tastatur"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Vælg tastaturer"</string>
     <string name="show_ime" msgid="9157568568695230830">"Vis indtastningsmetode"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Diverse"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Du angiver, hvor vigtige disse underretninger er."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Dette er vigtigt på grund af de personer, det handler om."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" forsøger at tilføje en ny bruger, men det er i øjeblikket forbudt."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" forsøger at tilføje en ny bruger, men grænsen for antal brugere er nået."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" forsøger at tilføje en ny bruger, men kontoen "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" findes allerede på denne enhed. Vil du fortsætte?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" forsøger at føje en ny bruger til kontoen "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Vil du fortsætte?"</string>
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 9cedd73..a28d2b8 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -45,7 +45,7 @@
     <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Mailbox"</string>
     <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
     <string name="mmiError" msgid="5154499457739052907">"Verbindungsproblem oder ungültiger MMI-Code."</string>
-    <string name="mmiFdnError" msgid="5224398216385316471">"Der Vorgang ist nur für Ihre zugelassenen Rufnummern möglich."</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"Der Vorgang ist nur für deine zugelassenen Rufnummern möglich."</string>
     <string name="serviceEnabled" msgid="8147278346414714315">"Dienst wurde aktiviert."</string>
     <string name="serviceEnabledFor" msgid="6856228140453471041">"Dienst wurde aktiviert für:"</string>
     <string name="serviceDisabled" msgid="1937553226592516411">"Dienst wurde deaktiviert."</string>
@@ -167,13 +167,13 @@
     <string name="low_memory" product="default" msgid="3475999286680000541">"Der Handyspeicher ist voll! Lösche Dateien, um Speicherplatz freizugeben."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Das Netzwerk wird möglicherweise überwacht."</string>
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Von einem unbekannten Dritten"</string>
-    <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"Vom Administrator Ihres Arbeitsprofils"</string>
+    <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"Vom Administrator deines Arbeitsprofils"</string>
     <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Von <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="work_profile_deleted" msgid="5005572078641980632">"Arbeitsprofil gelöscht"</string>
     <string name="work_profile_deleted_description" msgid="6305147513054341102">"Arbeitsprofil aufgrund fehlender Admin-App gelöscht"</string>
     <string name="work_profile_deleted_details" msgid="226615743462361248">"Die Admin-App für das Arbeitsprofil fehlt oder ist beschädigt. Daher wurden dein Arbeitsprofil und alle zugehörigen Daten gelöscht. Wende dich für weitere Hilfe an deinen Administrator."</string>
-    <string name="work_profile_deleted_description_dpm_wipe" msgid="6019770344820507579">"Ihr Arbeitsprofil ist auf diesem Gerät nicht mehr verfügbar."</string>
-    <string name="factory_reset_warning" msgid="5423253125642394387">"Die Daten auf Ihrem Gerät werden gelöscht."</string>
+    <string name="work_profile_deleted_description_dpm_wipe" msgid="6019770344820507579">"Dein Arbeitsprofil ist auf diesem Gerät nicht mehr verfügbar."</string>
+    <string name="factory_reset_warning" msgid="5423253125642394387">"Die Daten auf deinem Gerät werden gelöscht."</string>
     <string name="factory_reset_message" msgid="4905025204141900666">"Die Admin-App kann nicht verwendet werden, da sie beschädigt wurde oder Komponenten fehlen. Die Daten auf deinem Gerät werden nun gelöscht. Wende dich für weitere Hilfe an deinen Administrator."</string>
     <string name="me" msgid="6545696007631404292">"Eigene"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tablet-Optionen"</string>
@@ -194,9 +194,9 @@
     <string name="reboot_to_reset_title" msgid="4142355915340627490">"Auf Werkszustand zurück"</string>
     <string name="reboot_to_reset_message" msgid="2432077491101416345">"Neustart…"</string>
     <string name="shutdown_progress" msgid="2281079257329981203">"Wird heruntergefahren..."</string>
-    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Ihr Tablet wird heruntergefahren."</string>
-    <string name="shutdown_confirm" product="tv" msgid="476672373995075359">"Ihr Fernseher wird ausgeschaltet."</string>
-    <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"Ihre Uhr wird heruntergefahren."</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Dein Tablet wird heruntergefahren."</string>
+    <string name="shutdown_confirm" product="tv" msgid="476672373995075359">"Dein Fernseher wird ausgeschaltet."</string>
+    <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"Deine Uhr wird heruntergefahren."</string>
     <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefon wird heruntergefahren."</string>
     <string name="shutdown_confirm_question" msgid="2906544768881136183">"Möchtest du das Gerät herunterfahren?"</string>
     <string name="reboot_safemode_title" msgid="7054509914500140361">"Im abgesicherten Modus starten"</string>
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Fehlerbericht"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Fehlerbericht abrufen"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Bei diesem Fehlerbericht werden Daten zum aktuellen Status deines Geräts erfasst und als E-Mail versandt. Vom Start des Berichts bis zu seinem Versand kann es eine Weile dauern. Bitte habe etwas Geduld."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Lautlos-Modus"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Ton ist AUS."</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Ton ist AN."</string>
@@ -231,13 +240,13 @@
     <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakte"</string>
     <string name="permgroupdesc_contacts" msgid="6951499528303668046">"auf Kontakte zuzugreifen"</string>
     <string name="permgrouplab_location" msgid="7275582855722310164">"Standort"</string>
-    <string name="permgroupdesc_location" msgid="1346617465127855033">"auf den Standort Ihres Geräts zuzugreifen"</string>
+    <string name="permgroupdesc_location" msgid="1346617465127855033">"auf den Standort deines Geräts zuzugreifen"</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
     <string name="permgroupdesc_calendar" msgid="3889615280211184106">"auf Kalender zuzugreifen"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS zu senden und abzurufen"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Speicher"</string>
-    <string name="permgroupdesc_storage" msgid="637758554581589203">"auf Fotos, Medien und Dateien auf Ihrem Gerät zuzugreifen"</string>
+    <string name="permgroupdesc_storage" msgid="637758554581589203">"auf Fotos, Medien und Dateien auf deinem Gerät zuzugreifen"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"Audio aufzunehmen"</string>
     <string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
@@ -245,7 +254,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 zuzugreifen"</string>
+    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"auf Sensordaten zu deinen 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 du interagierst, werden abgerufen."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"\"Tippen &amp; Entdecken\" aktivieren"</string>
@@ -281,13 +290,13 @@
     <string name="permlab_sendSms" msgid="7544599214260982981">"SMS senden und abrufen"</string>
     <string name="permdesc_sendSms" msgid="7094729298204937667">"Ermöglicht der App, SMS zu senden. Dies kann zu unerwarteten Kosten führen. Schädliche Apps können Kosten verursachen, indem sie Nachrichten ohne deine Bestätigung senden."</string>
     <string name="permlab_readSms" msgid="8745086572213270480">"SMS oder MMS lesen"</string>
-    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Ermöglicht der App, auf Ihrem Tablet oder Ihrer SIM-Karte gespeicherte SMS zu lesen. Die App kann alle SMS lesen, unabhängig von Inhalt und Vertraulichkeit."</string>
-    <string name="permdesc_readSms" product="tv" msgid="5102425513647038535">"Ermöglicht der App, auf Ihrem Fernseher oder Ihrer SIM-Karte gespeicherte SMS zu lesen. Die App kann alle SMS lesen, unabhängig von Inhalt und Vertraulichkeit."</string>
-    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Ermöglicht der App, auf Ihrem Telefon oder Ihrer SIM-Karte gespeicherte SMS zu lesen. Die App kann alle SMS lesen, unabhängig von Inhalt und Vertraulichkeit."</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Ermöglicht der App, auf deinem Tablet oder deiner SIM-Karte gespeicherte SMS zu lesen. Die App kann alle SMS lesen, unabhängig von Inhalt und Vertraulichkeit."</string>
+    <string name="permdesc_readSms" product="tv" msgid="5102425513647038535">"Ermöglicht der App, auf deinem Fernseher oder deiner SIM-Karte gespeicherte SMS zu lesen. Die App kann alle SMS lesen, unabhängig von Inhalt und Vertraulichkeit."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Ermöglicht der App, auf deinem Telefon oder deiner SIM-Karte gespeicherte SMS zu lesen. Die App kann alle SMS lesen, unabhängig von Inhalt und Vertraulichkeit."</string>
     <string name="permlab_receiveWapPush" msgid="5991398711936590410">"Textnachrichten (WAP) empfangen"</string>
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Ermöglicht der App, WAP-Nachrichten zu empfangen und zu verarbeiten. Mit der Berechtigung können Nachrichten, die an dich gesendet wurden, überwacht und gelöscht werden, bevor sie dir angezeigt werden."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"Aktive Apps abrufen"</string>
-    <string name="permdesc_getTasks" msgid="7454215995847658102">"Ermöglicht der App, Informationen zu aktuellen und kürzlich ausgeführten Aufgaben abzurufen. Damit kann die App möglicherweise ermitteln, welche Apps auf Ihrem Gerät zum Einsatz kommen."</string>
+    <string name="permdesc_getTasks" msgid="7454215995847658102">"Ermöglicht der App, Informationen zu aktuellen und kürzlich ausgeführten Aufgaben abzurufen. Damit kann die App möglicherweise ermitteln, welche Apps auf deinem Gerät zum Einsatz kommen."</string>
     <string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"Profilinhaber und Geräteeigentümer verwalten"</string>
     <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Ermöglicht Apps das Einrichten der Profilinhaber und des Geräteeigentümers"</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"Aktive Apps neu ordnen"</string>
@@ -323,19 +332,19 @@
     <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"Ermöglicht der App, Daten zu den auf deinem Fernseher gespeicherten Kontakten zu ändern, einschließlich der Häufigkeit, mit der du bestimmte Kontakte angerufen, diesen E-Mails gesendet oder anderweitig mit ihnen kommuniziert hast. Die Berechtigung erlaubt Apps, Kontaktdaten zu löschen."</string>
     <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Ermöglicht der App, Daten zu Kontakten, die auf deinem Telefon gespeichert sind, zu ändern, einschließlich der Häufigkeit, mit der du bestimmte Kontakte angerufen, diesen E-Mails gesendet oder anderweitig mit ihnen kommuniziert hast. Die Berechtigung erlaubt Apps, Kontaktdaten zu löschen."</string>
     <string name="permlab_readCallLog" msgid="3478133184624102739">"Anrufliste lesen"</string>
-    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Ermöglicht der App, die Anrufliste Ihres Tablets zu lesen, einschließlich der Daten über ein- und ausgehende Anrufe. Die Berechtigung erlaubt Apps, Ihre Anruflistendaten zu speichern, und schädliche Apps können diese Daten ohne Ihr Wissen weiterleiten."</string>
-    <string name="permdesc_readCallLog" product="tv" msgid="5611770887047387926">"Ermöglicht der App, die Anrufliste Ihres Fernsehers zu lesen, einschließlich der Daten über ein- und ausgehende Anrufe. Diese Berechtigung ermöglicht es Apps, Daten aus Ihrer Anrufliste zu speichern. Schädliche Apps können so Ihre Anrufliste ohne Ihr Wissen weitergeben."</string>
-    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Ermöglicht der App, die Anrufliste Ihres Telefons zu lesen, einschließlich der Daten über ein- und ausgehende Anrufe. Die Berechtigung erlaubt Apps, Ihre Anruflistendaten zu speichern, und schädliche Apps können diese Daten ohne Ihr Wissen weiterleiten."</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Ermöglicht der App, die Anrufliste deines Tablets zu lesen, einschließlich der Daten über ein- und ausgehende Anrufe. Die Berechtigung erlaubt Apps, deine Anruflistendaten zu speichern, und schädliche Apps können diese Daten ohne dein Wissen weiterleiten."</string>
+    <string name="permdesc_readCallLog" product="tv" msgid="5611770887047387926">"Ermöglicht der App, die Anrufliste deines Fernsehers zu lesen, einschließlich der Daten über ein- und ausgehende Anrufe. Diese Berechtigung ermöglicht es Apps, Daten aus deiner Anrufliste zu speichern. Schädliche Apps können so deine Anrufliste ohne dein Wissen weitergeben."</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Ermöglicht der App, die Anrufliste deines Telefons zu lesen, einschließlich der Daten über ein- und ausgehende Anrufe. Die Berechtigung erlaubt Apps, deine Anruflistendaten zu speichern, und schädliche Apps können diese Daten ohne dein Wissen weiterleiten."</string>
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"Anrufliste bearbeiten"</string>
-    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Ermöglicht der App, die Anrufliste Ihres Tablets zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so Ihre Anrufliste löschen oder ändern."</string>
-    <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Ermöglicht der App, die Anrufliste Ihres Fernsehers zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so Ihre Anrufliste löschen oder ändern."</string>
-    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Ermöglicht der App, die Anrufliste Ihres Telefons zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so Ihre Anrufliste löschen oder ändern."</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Ermöglicht der App, die Anrufliste deines Tablets zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so deine Anrufliste löschen oder ändern."</string>
+    <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Ermöglicht der App, die Anrufliste deines Fernsehers zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so deine Anrufliste löschen oder ändern."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Ermöglicht der App, die Anrufliste deines Telefons zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so deine Anrufliste löschen oder ändern."</string>
     <string name="permlab_bodySensors" msgid="4683341291818520277">"Auf Körpersensoren wie z. B. Herzfrequenzmesser zugreifen"</string>
-    <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Ermöglicht der App, auf Daten von Sensoren zuzugreifen, die Ihre körperliche Verfassung überwachen, beispielsweise Ihren Puls"</string>
+    <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Ermöglicht der App, auf Daten von Sensoren zuzugreifen, die deine körperliche Verfassung überwachen, beispielsweise deinen Puls"</string>
     <string name="permlab_readCalendar" msgid="5972727560257612398">"Kalendertermine sowie vertrauliche Informationen lesen"</string>
-    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Ermöglicht der App, alle auf Ihrem Tablet gespeicherten Kalendertermine zu lesen, einschließlich der von Freunden und Kollegen. Damit kann die App möglicherweise Ihre Kalenderdaten unabhängig von der Vertraulichkeit weiterleiten oder speichern."</string>
-    <string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Ermöglicht der App, alle auf Ihrem Fernseher gespeicherten Kalendertermine zu lesen, einschließlich der von Freunden und Kollegen. Damit kann die App möglicherweise Ihre Kalenderdaten unabhängig von der Vertraulichkeit teilen oder speichern."</string>
-    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Ermöglicht der App, alle auf Ihrem Telefon gespeicherten Kalendertermine zu lesen, einschließlich der von Freunden und Kollegen. Damit kann die App möglicherweise Ihre Kalenderdaten unabhängig von der Vertraulichkeit weiterleiten oder speichern."</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Ermöglicht der App, alle auf deinem Tablet gespeicherten Kalendertermine zu lesen, einschließlich der von Freunden und Kollegen. Damit kann die App möglicherweise deine Kalenderdaten unabhängig von der Vertraulichkeit weiterleiten oder speichern."</string>
+    <string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Ermöglicht der App, alle auf deinem Fernseher gespeicherten Kalendertermine zu lesen, einschließlich der von Freunden und Kollegen. Damit kann die App möglicherweise deine Kalenderdaten unabhängig von der Vertraulichkeit teilen oder speichern."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Ermöglicht der App, alle auf deinem Telefon gespeicherten Kalendertermine zu lesen, einschließlich der von Freunden und Kollegen. Damit kann die App möglicherweise deine Kalenderdaten unabhängig von der Vertraulichkeit weiterleiten oder speichern."</string>
     <string name="permlab_writeCalendar" msgid="8438874755193825647">"Ohne das Wissen der Eigentümer Kalendertermine hinzufügen oder ändern und E-Mails an Gäste senden"</string>
     <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Ermöglicht der App, Termine, die du auf deinem Tablet ändern kannst, hinzuzufügen, zu entfernen und zu ändern, einschließlich derjenigen von Freunden und Kollegen. Damit kann die App Nachrichten senden, die so erscheinen, als stammten sie vom jeweiligen Kalenderinhaber, oder Termine ohne Wissen des Inhabers ändern."</string>
     <string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Ermöglicht der App, Termine, die du auf deinem Fernseher bearbeiten kannst ‒ einschließlich der von Freunden und Kollegen ‒, hinzuzufügen, zu entfernen und zu ändern. Dadurch kann die App möglicherweise Nachrichten senden, die scheinbar von Kalendereigentümern stammen, oder Termine ohne Wissen der Eigentümer ändern."</string>
@@ -349,11 +358,11 @@
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"Audio-Einstellungen ändern"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Ermöglicht der App, globale Audio-Einstellungen zu ändern, etwa die Lautstärke und den Lautsprecher für die Ausgabe."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"Audio aufnehmen"</string>
-    <string name="permdesc_recordAudio" msgid="4906839301087980680">"Ermöglicht der App, Ton mithilfe des Mikrofons aufzunehmen. Die Berechtigung erlaubt der App, Tonaufnahmen jederzeit und ohne Ihre Bestätigung durchzuführen."</string>
+    <string name="permdesc_recordAudio" msgid="4906839301087980680">"Ermöglicht der App, Ton mithilfe des Mikrofons aufzunehmen. Die Berechtigung erlaubt der App, Tonaufnahmen jederzeit und ohne deine Bestätigung durchzuführen."</string>
     <string name="permlab_sim_communication" msgid="2935852302216852065">"Befehle an die SIM senden"</string>
     <string name="permdesc_sim_communication" msgid="5725159654279639498">"Ermöglicht der App das Senden von Befehlen an die SIM-Karte. Dies ist äußerst risikoreich."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"Bilder und Videos aufnehmen"</string>
-    <string name="permdesc_camera" msgid="8497216524735535009">"Ermöglicht der App, Bilder und Videos mit der Kamera aufzunehmen. Die Berechtigung erlaubt der App, die Kamera jederzeit und ohne Ihre Bestätigung zu nutzen."</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"Ermöglicht der App, Bilder und Videos mit der Kamera aufzunehmen. Die Berechtigung erlaubt der App, die Kamera jederzeit und ohne deine Bestätigung zu nutzen."</string>
     <string name="permlab_vibrate" msgid="7696427026057705834">"Vibrationsalarm steuern"</string>
     <string name="permdesc_vibrate" msgid="6284989245902300945">"Ermöglicht der App, den Vibrationsalarm zu steuern"</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"Telefonnummern direkt anrufen"</string>
@@ -397,9 +406,9 @@
     <string name="permlab_changeWifiState" msgid="6550641188749128035">"WLAN-Verbindungen herstellen und trennen"</string>
     <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Ermöglicht der App, eine Verbindung zu WLAN-Zugriffspunkten herzustellen und solche zu trennen und Änderungen an der Gerätekonfiguration für WLAN-Netzwerke vorzunehmen."</string>
     <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"WLAN-Multicast-Empfang zulassen"</string>
-    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Ermöglicht der App, Pakete zu empfangen, die mithilfe von Multicast-Adressen an sämtliche Geräte in einem WLAN versendet wurden, nicht nur an Ihr Tablet. Dies kostet mehr Leistung als der Nicht-Multicast-Modus."</string>
-    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Ermöglicht der App, Pakete zu empfangen, die mithilfe von Multicast-Adressen an sämtliche Geräte in einem WLAN gesendet wurden, nicht nur an Ihren Fernseher. Dies kostet mehr Leistung als der Nicht-Multicast-Modus."</string>
-    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Ermöglicht der App, Pakete zu empfangen, die mithilfe von Multicast-Adressen an sämtliche Geräte in einem WLAN versendet wurden, nicht nur an Ihr Telefon. Dies kostet mehr Leistung als der Nicht-Multicast-Modus."</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Ermöglicht der App, Pakete zu empfangen, die mithilfe von Multicast-Adressen an sämtliche Geräte in einem WLAN versendet wurden, nicht nur an dein Tablet. Dies nicht mehr Leistung in Anspruch als der Nicht-Multicast-Modus."</string>
+    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Ermöglicht der App, Pakete zu empfangen, die mithilfe von Multicast-Adressen an sämtliche Geräte in einem WLAN gesendet wurden, nicht nur an deinen Fernseher. Dies nimmt mehr Leistung in Anspruch als der Nicht-Multicast-Modus."</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Ermöglicht der App, Pakete zu empfangen, die mithilfe von Multicast-Adressen an sämtliche Geräte in einem WLAN versendet wurden, nicht nur an dein Telefon. Dies nimmt mehr Leistung in Anspruch als der Nicht-Multicast-Modus."</string>
     <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"Auf Bluetooth-Einstellungen zugreifen"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Ermöglicht der App, das lokale Bluetooth-Tablet zu konfigurieren, Remote-Geräte zu erkennen und eine Verbindung zu diesen herzustellen"</string>
     <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"Ermöglicht der App, den lokalen Bluetooth-Fernseher zu konfigurieren, Remote-Geräte zu erkennen und ein Pairing mit diesen durchzuführen"</string>
@@ -779,13 +788,13 @@
     <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"Lesezeichen für Webseiten und das Webprotokoll lesen"</string>
     <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Ermöglicht der App, den Verlauf aller mit dem Browser besuchten URLs und sämtliche Lesezeichen des Browsers zu lesen. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Apps mit Internetfunktionen erzwungen werden."</string>
     <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"Lesezeichen für Webseiten setzen und das Webprotokoll aufzeichnen"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Ermöglicht der App, den Browserverlauf und die Lesezeichen auf Ihrem Tablet zu ändern. Damit kann die App Browserdaten löschen und ändern. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Apps mit Internetfunktionen erzwungen werden."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"Ermöglicht der App, den Browserverlauf und die Lesezeichen auf Ihrem Fernseher zu bearbeiten. Damit kann die App Browserdaten löschen und ändern. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Apps mit Internetfunktionen erzwungen werden."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Ermöglicht der App, den Browserverlauf und die Lesezeichen auf Ihrem Telefon zu ändern. Damit kann die App Browserdaten löschen und ändern. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Apps mit Internetfunktionen erzwungen werden."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Ermöglicht der App, den Browserverlauf und die Lesezeichen auf deinem Tablet zu ändern. Damit kann die App Browserdaten löschen und ändern. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Apps mit Internetfunktionen erzwungen werden."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"Ermöglicht der App, den Browserverlauf und die Lesezeichen auf deinem Fernseher zu bearbeiten. Damit kann die App Browserdaten löschen und ändern. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Apps mit Internetfunktionen erzwungen werden."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Ermöglicht der App, den Browserverlauf und die Lesezeichen auf deinem Telefon zu ändern. Damit kann die App Browserdaten löschen und ändern. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Apps mit Internetfunktionen erzwungen werden."</string>
     <string name="permlab_setAlarm" msgid="1379294556362091814">"Wecker stellen"</string>
     <string name="permdesc_setAlarm" msgid="316392039157473848">"Ermöglicht der App, einen Alarm in einer installierten Wecker-App einzurichten. Einige Wecker-Apps implementieren diese Funktion möglicherweise nicht."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"Mailbox-Nachrichten hinzufügen"</string>
-    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Ermöglicht der App, Nachrichten zu Ihrem Mailbox-Posteingang hinzuzufügen"</string>
+    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Ermöglicht der App, Nachrichten zu deinem Mailbox-Posteingang hinzuzufügen"</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Geolokalisierungsberechtigungen des Browsers ändern"</string>
     <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Ermöglicht der App, die Geolokalisierungsberechtigungen des Browsers zu ändern. Schädliche Apps können so Standortinformationen an beliebige Websites senden."</string>
     <string name="save_password_message" msgid="767344687139195790">"Möchtest du, dass der Browser dieses Passwort speichert?"</string>
@@ -919,7 +928,7 @@
     <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Skalieren"</string>
     <string name="screen_compat_mode_show" msgid="4013878876486655892">"Immer anzeigen"</string>
     <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Eine erneute Aktivierung ist in den Systemeinstellungen unter \"Apps &gt; Heruntergeladen\" möglich."</string>
-    <string name="smv_application" msgid="3307209192155442829">"Die App <xliff:g id="APPLICATION">%1$s</xliff:g> (Prozess <xliff:g id="PROCESS">%2$s</xliff:g>) hat gegen ihre selbsterzwungene StrictMode-Richtlinie verstoßen."</string>
+    <string name="smv_application" msgid="3307209192155442829">"Die App <xliff:g id="APPLICATION">%1$s</xliff:g> (Prozess <xliff:g id="PROCESS">%2$s</xliff:g>) hat gegen deine selbsterzwungene StrictMode-Richtlinie verstoßen."</string>
     <string name="smv_process" msgid="5120397012047462446">"Der Prozess <xliff:g id="PROCESS">%1$s</xliff:g> hat gegen seine selbsterzwungene StrictMode-Richtlinie verstoßen."</string>
     <string name="android_upgrading_title" msgid="1584192285441405746">"Android wird aktualisiert..."</string>
     <string name="android_start_title" msgid="8418054686415318207">"Android wird gestartet…"</string>
@@ -1001,8 +1010,8 @@
     <string name="sms_control_yes" msgid="3663725993855816807">"Zulassen"</string>
     <string name="sms_control_no" msgid="625438561395534982">"Nicht zulassen"</string>
     <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; möchte eine Nachricht an &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt; senden."</string>
-    <string name="sms_short_code_details" msgid="5873295990846059400">"Hierfür könnten Ihrem Mobilfunkkonto "<b>"Gebühren berechnet werden"</b>"."</string>
-    <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"Hierfür werden Ihrem Mobilfunkkonto Gebühren berechnet."</b></string>
+    <string name="sms_short_code_details" msgid="5873295990846059400">"Hierfür könnten deinem Mobilfunkkonto "<b>"Gebühren berechnet werden"</b>"."</string>
+    <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"Hierfür werden deinem Mobilfunkkonto Gebühren berechnet."</b></string>
     <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Senden"</string>
     <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Abbrechen"</string>
     <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Auswahl merken"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Für weitere Optionen tippen"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-Debugging"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Zum Deaktivieren berühren"</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Fehlerbericht mit Administrator teilen?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Dein IT-Administrator hat einen Fehlerbericht zur Fehlerbehebung angefordert."</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"AKZEPTIEREN"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ABLEHNEN"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Fehlerbericht wird aufgerufen…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Zum Abbrechen tippen"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Tastatur ändern"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Tastatur auswählen"</string>
     <string name="show_ime" msgid="9157568568695230830">"Eingabemethode anzeigen"</string>
@@ -1107,7 +1110,7 @@
     <string name="ime_action_default" msgid="2840921885558045721">"Ausführen"</string>
     <string name="dial_number_using" msgid="5789176425167573586">"Nummer\nmit <xliff:g id="NUMBER">%s</xliff:g> wählen"</string>
     <string name="create_contact_using" msgid="4947405226788104538">"Neuer Kontakt\nmit <xliff:g id="NUMBER">%s</xliff:g> erstellen"</string>
-    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Die folgenden Apps benötigen die Berechtigung zum aktuellen und zukünftigen Zugriff auf Ihr Konto."</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Die folgenden Apps benötigen die Berechtigung zum aktuellen und zukünftigen Zugriff auf dein Konto."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Möchtest du diese Anfrage zulassen?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Zugriffsanforderung"</string>
     <string name="allow" msgid="7225948811296386551">"Zulassen"</string>
@@ -1326,7 +1329,7 @@
     <string name="user_logging_out_message" msgid="8939524935808875155">"<xliff:g id="NAME">%1$s</xliff:g> wird abgemeldet…"</string>
     <string name="owner_name" msgid="2716755460376028154">"Eigentümer"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Fehler"</string>
-    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Ihr Administrator lässt diese Änderung nicht zu."</string>
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Dein Administrator lässt diese Änderung nicht zu."</string>
     <string name="app_not_found" msgid="3429141853498927379">"Für diese Aktion wurde keine App gefunden."</string>
     <string name="revoke" msgid="5404479185228271586">"Aufheben"</string>
     <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
@@ -1453,10 +1456,10 @@
     <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Vor dem Beenden nach Entsperrungsmuster fragen"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Vor dem Beenden nach Passwort fragen"</string>
     <string name="dock_non_resizeble_text" msgid="9156251681042762723">"Die Größe der App kann nicht angepasst werden. Scrolle sie mit zwei Fingern."</string>
-    <string name="package_installed_device_owner" msgid="8420696545959087545">"Von Ihrem Administrator installiert"</string>
-    <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="package_installed_device_owner" msgid="8420696545959087545">"Von deinem Administrator installiert"</string>
+    <string name="package_updated_device_owner" msgid="8856631322440187071">"Von deinem Administrator aktualisiert"</string>
+    <string name="package_deleted_device_owner" msgid="7650577387493101353">"Von deinem 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 deinem Gerät synchronisiert werden, werden möglicherweise erst nach dem Öffnen aktualisiert.\n\nDer Energiesparmodus wird automatisch deaktiviert, wenn dein Gerät aufgeladen wird."</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>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Sonstige"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Du legst die Wichtigkeit dieser Benachrichtigungen fest."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Diese Benachrichtigung ist aufgrund der beteiligten Personen wichtig."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" versucht, einen neuen Nutzer hinzuzufügen. Dieser Vorgang ist momentan nicht zulässig."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" versucht, einen neuen Nutzer hinzuzufügen. Die maximal zulässige Anzahl an Nutzern ist aber schon erreicht."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" versucht, einen neuen Nutzer hinzuzufügen, aber das Konto "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" besteht bereits auf diesem Gerät. Trotzdem fortfahren?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" versucht, einen neuen Nutzer für das Konto "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" hinzuzufügen. Fortfahren?"</string>
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index d2be252..40d2e5b 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Αναφορά σφαλμάτων"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Λήψη αναφοράς σφάλματος"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Θα συλλέξει πληροφορίες σχετικά με την τρέχουσα κατάσταση της συσκευής σας και θα τις στείλει μέσω μηνύματος ηλεκτρονικού ταχυδρομείου. Απαιτείται λίγος χρόνος για τη σύνταξη της αναφοράς σφάλματος και την αποστολή της. Κάντε λίγη υπομονή."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Λειτουργία σίγασης"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Ο ήχος είναι απενεργοποιημένος"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Ο ήχος είναι ενεργοποιημένος"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Αγγίξτε για περισσότερες επιλογές."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Συνδέθηκε ο εντοπισμός σφαλμάτων USB"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Απεν. του εντοπ. σφαλμάτων USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Να κοινοποιηθεί η αναφορά σφάλματος στο διαχειριστή;"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Ο διαχειριστής σας IT ζήτησε μια αναφορά σφάλματος για να συμβάλει στην αντιμετώπιση του προβλήματος"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ΑΠΟΔΟΧΗ"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ΑΠΟΡΡΙΨΗ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Λήψη αναφοράς σφάλματος…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Αγγίξτε για ακύρωση"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Αλλαγή πληκτρολογίου"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Επιλογή πληκτρολογίων"</string>
     <string name="show_ime" msgid="9157568568695230830">"Εμφάνιση μεθόδου εισαγ."</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Διάφορα"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Μπορείτε να ρυθμίσετε τη βαρύτητα αυτών των ειδοποιήσεων."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Αυτό είναι σημαντικό λόγω των ατόμων που συμμετέχουν."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315">"Το "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" προσπαθεί να προσθέσει έναν νέο χρήστη, αλλά προς το παρόν αυτό απαγορεύεται."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266">"Το "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" προσπαθεί να προσθέσει έναν νέο χρήστη, αλλά έχετε φτάσει το όριο χρηστών."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789">"Το "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" προσπαθεί να προσθέσει έναν νέο χρήστη, αλλά ο λογαριασμός "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" υπάρχει ήδη σε αυτήν τη συσκευή. Θέλετε να συνεχίσετε ούτως ή άλλως;"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392">"Το "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" προσπαθεί να προσθέσει έναν νέο χρήστη για το λογαριασμό "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Θέλετε να συνεχίσετε;"</string>
 </resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index c49d9d5..80d2efe 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Bug report"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Take bug report"</string>
     <string name="bugreport_message" msgid="398447048750350456">"This will collect information about your current device state, to send as an email message. It will take a little time from starting the bug report until it is ready to be sent. Please be patient."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Silent mode"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Sound is OFF"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Sound is ON"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Touch for more options."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Touch to disable USB debugging."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Share bug report with admin?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Your IT admin requested a bug report to help troubleshoot"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACCEPT"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"DECLINE"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Taking bug report…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Touch to cancel"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Change keyboard"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Choose keyboards"</string>
     <string name="show_ime" msgid="9157568568695230830">"Show input method"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index c49d9d5..80d2efe 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Bug report"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Take bug report"</string>
     <string name="bugreport_message" msgid="398447048750350456">"This will collect information about your current device state, to send as an email message. It will take a little time from starting the bug report until it is ready to be sent. Please be patient."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Silent mode"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Sound is OFF"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Sound is ON"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Touch for more options."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Touch to disable USB debugging."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Share bug report with admin?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Your IT admin requested a bug report to help troubleshoot"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACCEPT"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"DECLINE"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Taking bug report…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Touch to cancel"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Change keyboard"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Choose keyboards"</string>
     <string name="show_ime" msgid="9157568568695230830">"Show input method"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index c49d9d5..80d2efe 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Bug report"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Take bug report"</string>
     <string name="bugreport_message" msgid="398447048750350456">"This will collect information about your current device state, to send as an email message. It will take a little time from starting the bug report until it is ready to be sent. Please be patient."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Silent mode"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Sound is OFF"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Sound is ON"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Touch for more options."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Touch to disable USB debugging."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Share bug report with admin?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Your IT admin requested a bug report to help troubleshoot"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACCEPT"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"DECLINE"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Taking bug report…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Touch to cancel"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Change keyboard"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Choose keyboards"</string>
     <string name="show_ime" msgid="9157568568695230830">"Show input method"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 3df4952..1900e8d 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Informe de errores"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Iniciar informe de errores"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Se recopilará información sobre el estado actual de tu dispositivo, que se enviará por correo. Pasarán unos minutos desde que se inicie el informe de errores hasta que se envíe, por lo que te recomendamos que tengas paciencia."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modo silencioso"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"El sonido está Desactivado"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"El sonido está Activado"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Toca para ver más opciones."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración por USB conectada"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca para desactivar la depuración por USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"¿Quieres compartir el informe de errores con el administrador?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"El administrador de TI solicitó un informe de errores para ayudar a solucionar el problema"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACEPTAR"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"RECHAZAR"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Realizando un informe de errores…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Toca para cancelar"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Cambiar el teclado"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Seleccionar teclados"</string>
     <string name="show_ime" msgid="9157568568695230830">"Mostrar método de entrada"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Varios"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Estableciste la importancia de estas notificaciones."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Es importante debido a las personas involucradas."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está intentando agregar un usuario nuevo, pero esta app no está permitida."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está intentado agregar un usuario nuevo, pero ya se alcanzó el límite máximo de usuarios."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está intentado agregar un usuario nuevo, pero la cuenta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ya existe en este dispositivo. ¿Deseas continuar de todas formas?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está intentando agregar un usuario nuevo a la cuenta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". ¿Deseas continuar?"</string>
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index a8aea66..846b9dc 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Informe de error"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Crear informe de errores"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Se recopilará información sobre el estado actual de tu dispositivo y se enviará por correo electrónico. Pasarán unos minutos desde que empiece a generarse el informe de errores hasta que se envíe."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modo silencio"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"El sonido está desactivado. Activar"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"El sonido está activado. Desactivar"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Toca para obtener más opciones"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración USB habilitada"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca aquí para inhabilitarla"</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"¿Compartir informe de errores con el administrador?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Tu administrador de TI ha solicitado un informe de errores para solucionar problemas"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACEPTAR"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"RECHAZAR"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Creando informe de errores…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Toca para cancelar"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Cambiar teclado"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Elegir teclados"</string>
     <string name="show_ime" msgid="9157568568695230830">"Mostrar método de entrada"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Varios"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Tú determinas la importancia de estas notificaciones."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Esto es importante por los usuarios implicados."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" quiere añadir un usuario nuevo, pero no está permitido."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" quiere añadir un usuario nuevo, pero se ha alcanzado el límite de usuarios."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" quiere añadir un usuario nuevo, pero la cuenta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ya existe en este dispositivo. ¿Quieres continuar de todas formas?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" quiere añadir un usuario nuevo a la cuenta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". ¿Quieres continuar?"</string>
 </resources>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 36e1f89..09d031b 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Veaaruanne"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Veaaruande võtmine"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Nii kogutakse teavet teie seadme praeguse oleku kohta, et saata see meilisõnumina. Enne kui saate veaaruande ära saata, võtab selle loomine natuke aega; varuge kannatust."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Hääletu režiim"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Heli on VÄLJAS"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Heli on SEES"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Puudutage rohkemate valikute kuvamiseks."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-silumine ühendatud"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Puudutage USB-silumise keelamiseks."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Kas jagada veaaruannet administraatoriga?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IT-administraator taotles veaaruannet, mis aitaks vigu otsida"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"NÕUSTU"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"KEELDU"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Veaaruande võtmine …"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Puudutage tühistamiseks"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Klaviatuuri muutmine"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Vali klaviatuurid"</string>
     <string name="show_ime" msgid="9157568568695230830">"Sisestusmeetodi kuvamine"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Mitmesugust"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Teie määrasite nende märguannete tähtsuse."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"See on tähtis osalevate inimeste tõttu."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" üritab lisada uut kasutajat, kuid see on praegu keelatud."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" üritab lisada uut kasutajat, ent olete jõudnud kasutajate maksimumarvuni."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" üritab lisada uut kasutajat, ent konto "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" on juba seadmes olemas. Kas soovite siiski jätkata?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" üritab lisada uut kasutajat kontole "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Kas soovite jätkata?"</string>
 </resources>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index 32c5970..59cc71e 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Akatsen txostena"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Sortu akatsen txostena"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Gailuaren uneko egoerari buruzko informazioa bilduko da, mezu elektroniko gisa bidaltzeko. Minutu batzuk igaroko dira akatsen txostena sortzen hasten denetik bidaltzeko prest egon arte. Itxaron, mesedez."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Isilik modua"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Soinua DESAKTIBATUTA dago"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Soinua AKTIBATUTA dago"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Ukitu aukera gehiago ikusteko."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB arazketa konektatuta"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB arazketa desgaitzeko, ukitu hau."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Partekatu nahi duzu administratzailearekin akatsen txostena?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IKT administratzaileak akatsen txostena eskatu du arazoa konpontzen laguntzeko"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ONARTU"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"BAZTERTU"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Akatsen txostena sortzen…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Ukitu bertan behera uzteko"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Aldatu teklatua"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Aukeratu teklatuak"</string>
     <string name="show_ime" msgid="9157568568695230830">"Erakutsi idazketa-metodoa"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Askotarikoak"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Zuk ezarri zenuen jakinarazpen hauen garrantzia."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Garrantzitsua da eragiten dien pertsonengatik."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" beste erabiltzaile bat gehitzen saiatzen ari da, baina unean debekatuta dago."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" beste erabiltzaile bat gehitzen saiatzen ari da, baina erabiltzaileen mugara irisi da."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" beste erabiltzaile bat gehitzen saiatzen ari da, baina "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" badago gailuan. Jarraitu nahi duzu halere?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" beste erabiltzaile bat gehitzen saiatzen ari da "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" kontuan. Jarraitu nahi duzu?"</string>
 </resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index b518725..41c6729 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"گزارش اشکال"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"گرفتن گزارش اشکال"</string>
     <string name="bugreport_message" msgid="398447048750350456">"این گزارش اطلاعات مربوط به وضعیت دستگاه کنونی شما را جمع‌آوری می‌کند تا به صورت یک پیام ایمیل ارسال شود. از زمان شروع گزارش اشکال تا آماده شدن برای ارسال اندکی زمان می‌برد؛ لطفاً شکیبا باشید."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"حالت ساکت"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"صدا خاموش است"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"صدا روشن است"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"برای گزینه‌های بیشتر لمس کنید."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏اشکال‌زدایی USB متصل شد"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"‏غیرفعال‌کردن اشکال‌زدایی‌USB: با لمس آن."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"گزارش اشکال را با سرپرست سیستم به اشتراک می‌گذارید؟"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"سرپرست فناوری اطلاعات شما برای کمک به عیب‌یابی، گزارش اشکال درخواست کرد"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"پذیرفتن"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"نپذیرفتن"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"درحال گرفتن گزارش اشکال…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"برای لغو کردن لمس کنید"</string>
     <string name="select_input_method" msgid="8547250819326693584">"تغییر صفحه‌کلید"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"انتخاب صفحه‌کلیدها"</string>
     <string name="show_ime" msgid="9157568568695230830">"نمایش روش ورودی"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"متفرقه"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"شما اهمیت این اعلان‌ها را تنظیم می‌کنید."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"به دلیل افراد درگیر مهم است."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" در تلاش است کاربر جدیدی اضافه کند، اما در حال حاضر این اقدام ممنوع است."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" در تلاش است کاربر جدیدی اضافه کند، اما تعداد کاربران به حداکثر مجاز رسیده است."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" در تلاش است کاربر جدیدی اضافه کند، اما حساب "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" از قبل در این دستگاه وجود دارد. در هر صورت ادامه داده شود؟"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" در تلاش است کاربر جدیدی برای حساب "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" اضافه کند. ادامه می‌دهید؟"</string>
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 7b0d807..70b1bd28 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Virheraportti"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Luo virheraportti"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Toiminto kerää tietoja laitteen tilasta ja lähettää ne sähköpostitse. Virheraportti on valmis lähetettäväksi hetken kuluttua - kiitos kärsivällisyydestäsi."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Äänetön tila"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Äänet ovat POISSA KÄYTÖSTÄ"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Äänet ovat KÄYTÖSSÄ"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Lisää vaihtoehtoja koskettamalla"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-vianetsintä yhdistetty"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Sulje USB-vianetsintä koskettamalla."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Jaetaanko virheraportti järjestelmänvalvojalle?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IT-järjestelmänvalvojasi pyysi virheraporttia voidakseen auttaa vianetsinnässä."</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"HYVÄKSY"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"HYLKÄÄ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Luodaan virheraporttia…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Peruuta koskettamalla"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Vaihda näppäimistö"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Valitse näppäimistöt"</string>
     <string name="show_ime" msgid="9157568568695230830">"Näytä syöttötapa"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Muut"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Voit valita näiden ilmoitusten tärkeyden."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Tämä on tärkeää siihen liittyvien ihmisten perusteella."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" yrittää lisätä uutta käyttäjää, mutta se on tällä hetkellä estetty."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" yrittää lisätä uutta käyttäjää, mutta käyttäjiä on jo enimmäismäärä."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" yrittää lisätä uutta käyttäjää, mutta tili "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" on jo tässä laitteessa. Jatketaanko silti?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" yrittää lisätä uutta käyttäjää tilille "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Jatketaanko?"</string>
 </resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 16f7d46..4cbda57 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Rapport de bogue"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Créer un rapport de bogue"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Cela permet de recueillir des informations concernant l\'état actuel de votre appareil. Ces informations sont ensuite envoyées sous forme de courriel. Merci de patienter pendant la préparation du rapport de bogue. Cette opération peut prendre quelques instants."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mode silencieux"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Le son est désactivé."</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Le son est activé."</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Touchez pour afficher plus d\'options."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB connecté"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Appuyez pour désactiver le débogage USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Partager le rapport de bogue avec l\'administrateur?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Votre administrateur informatique a demandé un rapport de bogue pour l\'aider à résoudre le problème"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACCEPTER"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"REFUSER"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Création d\'un rapport de bogue en cours..."</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Touchez pour annuler"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Changer de clavier"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Choisir les claviers"</string>
     <string name="show_ime" msgid="9157568568695230830">"Afficher le mode d\'entrée"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Divers"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Vous définissez l\'importance de ces notifications."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Ces notifications sont importantes en raison des participants."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" essaie d\'ajouter un utilisateur, mais n\'y est pas autorisé."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" essaie d\'ajouter un utilisateur, mais le nombre maximal d\'utilisateurs a été atteint."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" essaie d\'ajouter un utilisateur, mais le compte "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" existe déjà sur cet appareil. Continuer?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" essaie d\'ajouter un utilisateur, mais le compte "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Continuer?"</string>
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index f90e65d..2daaff4 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Rapport de bug"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Créer un rapport de bug"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Cela permet de recueillir des informations concernant l\'état actuel de votre appareil. Ces informations sont ensuite envoyées sous forme d\'e-mail. Merci de patienter pendant la préparation du rapport de bug. Cette opération peut prendre quelques instants."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mode silencieux"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Le son est désactivé."</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Le son est activé."</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Appuyez pour afficher plus d\'options"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB activé"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Appuyez pour désact. débogage USB"</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Partager le rapport de bug avec l\'administrateur ?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Votre administrateur informatique a demandé un rapport de bug pour l\'aider à résoudre le problème."</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACCEPTER"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"REFUSER"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Création du rapport de bug…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Appuyer pour annuler"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Changer de clavier"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Sélectionner des claviers"</string>
     <string name="show_ime" msgid="9157568568695230830">"Afficher mode de saisie"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Divers"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Vous définissez l\'importance de ces notifications."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Ces notifications sont importantes en raison des participants."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" essaie d\'ajouter un utilisateur, mais n\'y est pas autorisé."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" essaie d\'ajouter un utilisateur, mais le nombre maximal d\'utilisateurs a été atteint."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" essaie d\'ajouter un utilisateur, mais le compte "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" existe déjà sur cet appareil. Continuer ?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" essaie d\'ajouter un utilisateur au compte "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Continuer ?"</string>
 </resources>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index 14d91fc..a74a013 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Informe de erros"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Crear informe de erros"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Este informe recompilará información acerca do estado actual do teu dispositivo para enviala en forma de mensaxe de correo electrónico. O informe de erros tardará un pouco en completarse desde o seu inicio ata que estea preparado para enviarse, polo que che recomendamos que teñas paciencia."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modo de silencio"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"O son está desactivado"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"O son está activado"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Toca para ver máis opcións."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración USB conectada"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca aquí para desactivala"</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Queres compartir o informe de erros co administrador?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"O teu administrador de TI solicitou un informe de erros para axudar a solucionar problemas"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACEPTAR"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ANULAR"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Creando informe de erros…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Tocar para cancelar o informe de erros"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Cambiar teclado"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Seleccionar teclados"</string>
     <string name="show_ime" msgid="9157568568695230830">"Mostra método de entrada"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Varios"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Ti defines a importancia destas notificacións."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"É importante polas persoas involucradas."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está tentando engadir un usuario novo, pero está prohibido."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está tentando engadir un usuario novo, pero alcanzouse o límite de usuarios."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está tentando engadir un usuario novo, pero a conta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" xa existe neste dispositivo. Queres continuar igualmente?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está tentando engadir un usuario novo á conta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Queres continuar?"</string>
 </resources>
diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml
index 86b12b8..97404e9 100644
--- a/core/res/res/values-gu-rIN/strings.xml
+++ b/core/res/res/values-gu-rIN/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"બગ રિપોર્ટ"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"બગ રિપોર્ટ લો"</string>
     <string name="bugreport_message" msgid="398447048750350456">"આ, એક ઇ-મેઇલ સંદેશ તરીકે મોકલવા માટે, તમારા વર્તમાન ઉપકરણ સ્થિતિ વિશેની માહિતી એકત્રિત કરશે. એક બગ રિપોર્ટ પ્રારંભ કરીને તે મોકલવા માટે તૈયાર ન થઈ જાય ત્યાં સુધી તેમાં થોડો સમય લાગશે; કૃપા કરીને ધીરજ રાખો."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"સાઇલેન્ટ મોડ"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"અવાજ બંધ છે"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ધ્વનિ ચાલુ છે"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"વધુ વિકલ્પો માટે ટચ કરો."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ડીબગિંગ કનેક્ટ થયું."</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ડીબગિંગ અક્ષમ કરવા માટે ટચ કરો."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"વ્યવસ્થાપક સાથે બગ રિપોર્ટ શેર કરીએ?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"તમારા IT વ્યવસ્થાપક એ સમસ્યા નિવારણમાં સહાય માટે બગ રિપોર્ટની વિનંતી કરી છે"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"સ્વીકારો"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"નકારો"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"બગ રિપોર્ટ લઈ રહ્યાં છે…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"રદ કરવા માટે ટચ કરો"</string>
     <string name="select_input_method" msgid="8547250819326693584">"કીબોર્ડ બદલો"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"કીબોર્ડ્સ પસંદ કરો"</string>
     <string name="show_ime" msgid="9157568568695230830">"ઇનપુટ પદ્ધતિ બતાવો"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 01f5d6c..39bc701 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"बग रिपोर्ट"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"बग रिपोर्ट प्राप्त करें"</string>
     <string name="bugreport_message" msgid="398447048750350456">"ईमेल संदेश के रूप में भेजने के लिए, इसके द्वारा आपके डिवाइस की वर्तमान स्थिति के बारे में जानकारी एकत्र की जाएगी. बग रिपोर्ट प्रारंभ करने से लेकर भेजने के लिए तैयार होने तक कुछ समय लगेगा; कृपया धैर्य रखें."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"मौन मोड"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ध्‍वनि बंद है"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ध्‍वनि चालू है"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"और विकल्पों के लिए स्पर्श करें."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डीबग कनेक्ट किया गया"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB डीबग करना अक्षम करने के लिए स्‍पर्श करें."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"व्यवस्थापक के साथ बग रिपोर्ट साझा करें?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"समस्या निवारण में सहायता हेतु आपके आईटी व्यवस्थापक ने बग रिपोर्ट के लिए अनुरोध किया है"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"स्वीकार करें"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"अस्वीकार करें"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"बग रिपोर्ट प्राप्त की जा रही है…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"रद्द करने के लिए स्पर्श करें"</string>
     <string name="select_input_method" msgid="8547250819326693584">"कीबोर्ड बदलें"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"कीबोर्ड चुनें"</string>
     <string name="show_ime" msgid="9157568568695230830">"इनपुट विधि दिखाएं"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index f837fe0..fbb347f 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -212,6 +212,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Izvješće o bugovima"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Izvješće o programskoj pogrešci"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Time će se prikupiti podaci o trenutačnom stanju vašeg uređaja koje ćete nam poslati u e-poruci. Za pripremu izvješća o programskoj pogrešci potrebno je nešto vremena pa vas molimo za strpljenje."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Bešumni način"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Zvuk je isključen"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Zvuk je uključen"</string>
@@ -1039,18 +1048,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Dodirnite za više opcija."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Priključen je alat za uklanjanje pogrešaka USB-om"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Dodirnite da se onemogući otklanjanje pogrešaka USB-om."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Želite li podijeliti izvješće o programskoj pogrešci s administratorom?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Vaš IT administrator zatražio je izvješće o programskoj pogrešci radi lakšeg rješavanja problema"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"PRIHVATI"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ODBIJ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Izrada izvješća o programskoj pogrešci…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Dodirnite da biste otkazali"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Promjena tipkovnice"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Odaberi tipkovnice"</string>
     <string name="show_ime" msgid="9157568568695230830">"Prikaz način unosa"</string>
@@ -1542,12 +1545,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Razno"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Postavili ste važnost tih obavijesti."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Važno je zbog uključenih osoba."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" pokušava dodati novog korisnika, no to trenutačno nije dopušteno."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" pokušava dodati novog korisnika, no dosegnuto je ograničenje broja korisnika."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" pokušava dodati novog korisnika, ali račun "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" već postoji na ovom uređaju. Želite li ipak nastaviti?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" pokušava dodati novog korisnika za račun "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Želite li nastaviti?"</string>
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index a5f02b3..569e725 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Programhiba bejelentése"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Hibajelentés készítése"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Ezzel információt fog gyűjteni az eszköz jelenlegi állapotáról, amelyet a rendszer e-mailben fog elküldeni. Kérjük, legyen türelemmel, amíg a hibajelentés elkészül, és küldhető állapotba kerül."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Néma üzemmód"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Hang kikapcsolva"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Hang bekapcsolva"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Érintse meg a további lehetőségekhez."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hibakereső csatlakoztatva"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Érintse meg az USB hibakeresés kikapcsolásához."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Megosztja a hibajelentést a rendszergazdával?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"A rendszergazda hibajelentést kért, hogy segíthessen a problémamegoldásban"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ELFOGADOM"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ELUTASÍTOM"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Hibajelentés készítése…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"A visszavonáshoz érintse meg"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Billentyűzet megváltoztatása"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Billentyűzetek kiválasztása"</string>
     <string name="show_ime" msgid="9157568568695230830">"Beviteli mód megjelenítése"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 290ec43..cbe058e 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Վրիպակի զեկույց"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Գրել սխալի զեկույց"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Սա տեղեկություններ կհավաքագրի ձեր սարքի առկա կարգավիճակի մասին և կուղարկի այն էլեկտրոնային նամակով: Որոշակի ժամանակ կպահանջվի վրիպակի մասին զեկուցելու պահից սկսած մինչ ուղարկելը: Խնդրում ենք փոքր-ինչ համբերատար լինել:"</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Անձայն ռեժիմ"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Ձայնը անջատված է"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Ձայնը միացված է"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Հպեք՝ լրացուցիչ ընտրանքների համար:"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB վրիպազերծումը միացված է"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Հպեք` USB կարգաբերումը կասեցնելու համար:"</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Ուղարկե՞լ վրիպակի զեկույց ադմինիստրատորին:"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Անսարքությունների վերացման նպատակով ձեր ՏՏ ադմինիստրատորին անհրաժեշտ է վրիպակի զեկույց"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ԸՆԴՈՒՆԵԼ"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ՄԵՐԺԵԼ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Վրիպակի զեկույցի ստեղծում…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Հպեք՝ չեղարկելու համար"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Փոխել ստեղնաշարը"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Ընտրել ստեղնաշար"</string>
     <string name="show_ime" msgid="9157568568695230830">"Ցուցադրել մուտքագրման եղանակը"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Զանազան"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Դուք սահմանել եք այս ծանուցումների կարևորությունը:"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Կարևոր է, քանի որ որոշակի մարդիկ են ներգրավված:"</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" հավելվածը փորձում է նոր օգտվող ավելացնել, սակայն ներկայումս արգելափակված է:"</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" հավելվածը փորձում է նոր օգտվող ավելացնել, սակայն օգտվողների քանակի սահմանաչափը լրացել է:"</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" հավելվածը փորձում է նոր օգտվող ավելացնել, սակայն "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" հաշիվն այս սարքում արդեն գոյություն ունի: Շարունակե՞լ:"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" հավելվածը փորձում է "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" հաշվի համար նոր օգտվող ավելացնել: Շարունակե՞լ:"</string>
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 1943850..15efd94 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Laporan bug"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Ambil laporan bug"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Ini akan mengumpulkan informasi status perangkat Anda saat ini, untuk dikirimkan sebagai pesan email. Harap bersabar, mungkin perlu waktu untuk memulai laporan bug hingga siap dikirim."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mode senyap"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Suara MATI"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Suara AKTIF"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Sentuh untuk opsi lainnya."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Debugging USB terhubung"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Sentuh untuk menonaktifkan debugging USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Bagikan laporan bug kepada admin?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Admin IT meminta laporan bug untuk membantu memecahkan masalah"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"SETUJU"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"TOLAK"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Mengambil laporan bug…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Sentuh untuk membatalkan"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Ubah keyboard"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Pilih keyboard"</string>
     <string name="show_ime" msgid="9157568568695230830">"Tampilkan metode masukan"</string>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index 1b4968c..88d58b0 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Villutilkynning"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Útbúa villutilkynningu"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Þetta safnar upplýsingum um núverandi stöðu tækisins til að senda með tölvupósti. Það tekur smástund frá því villutilkynningin er ræst og þar til hún er tilbúin til sendingar – sýndu biðlund."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Hljóðlaus stilling"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"SLÖKKT er á hljóði"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"KVEIKT er á hljóði"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Snertu til að fá fleiri valkosti."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-villuleit tengd"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Snertu til að slökkva á USB-villuleit."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Deila villutilkynningu með kerfisstjóra?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Kerfisstjórinn þinn óskaði eftir villutilkynningu til að auðvelda úrræðaleit"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"SAMÞYKKJA"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"HAFNA"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Tekur við villutilkynningu…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Snertu til að hætta við"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Skipta um lyklaborð"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Velja lyklaborð"</string>
     <string name="show_ime" msgid="9157568568695230830">"Sýna innsláttaraðferð"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Ýmislegt"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Þú stilltir mikilvægi þessara tilkynninga."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Þetta er mikilvægt vegna fólksins sem tekur þátt í þessu."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" er að reyna að bæta við nýjum notanda, en er sjálfur á bannlista."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" er að reyna að bæta við nýjum notanda, en notandahámarkinu hefur þegar verið náð."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" er að reyna að bæta við nýjum notanda, en reikningurinn "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" er nú þegar til á þessu tæki. Halda samt áfram?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" er að reyna að bæta nýjum notanda við reikninginn "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Halda áfram?"</string>
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index e469c46..da34b35 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Segnalazione di bug"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Apri segnalazione bug"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Verranno raccolte informazioni sullo stato corrente del dispositivo che saranno inviate sotto forma di messaggio email. Passerà un po\' di tempo prima che la segnalazione di bug aperta sia pronta per essere inviata; ti preghiamo di avere pazienza."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modalità silenziosa"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Audio non attivo"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Audio attivo"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Tocca per visualizzare più opzioni."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Debug USB collegato"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Tocca per disattivare il debug USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Condividere la segnalazione di bug con l\'amministratore?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"L\'amministratore IT ha richiesto una segnalazione di bug per poter risolvere più facilmente i problemi"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACCETTO"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"RIFIUTO"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Recupero della segnalazione di bug…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Tocca per annullare"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Cambia tastiera"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Scegli tastiera"</string>
     <string name="show_ime" msgid="9157568568695230830">"Mostra metodo immissione"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index fd7cc7b..54c1fb1 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -213,6 +213,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"דיווח על באג"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"שלח דיווח על באג"</string>
     <string name="bugreport_message" msgid="398447048750350456">"פעולה זו תאסוף מידע על מצב המכשיר הנוכחי שלך על מנת לשלוח אותו כהודעת אימייל. היא תימשך זמן קצר מרגע פתיחת דיווח הבאג ועד לשליחת ההודעה בפועל. אנא המתן בסבלנות."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"מצב שקט"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"הקול כבוי"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"קול מופעל"</string>
@@ -1046,18 +1055,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"גע להצגת עוד אפשרויות."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏ניפוי באגים של USB מחובר"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"‏גע כדי להשבית ניפוי באגים בהתקן ה-USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"האם לשתף את הדוח על הבאג עם מנהל המערכת?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"‏מנהל ה-IT ביקש דוח על באג כדי לסייע בפתרון בעיות"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"אישור"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"דחייה"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"עיבוד דוח על באג..."</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"גע כדי לבטל"</string>
     <string name="select_input_method" msgid="8547250819326693584">"שינוי מקלדת"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"בחר מקלדות"</string>
     <string name="show_ime" msgid="9157568568695230830">"הצג שיטת קלט"</string>
@@ -1560,12 +1563,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"שונות"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"אתה מגדיר את החשיבות של ההודעות האלה."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"ההודעה חשובה בשל האנשים המעורבים."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" מנסה להוסיף משתמש חדש, אך אין הרשאה מתאימה."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" מנסה להוסיף משתמש חדש, אך מכסת המשתמשים כבר מלאה."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" מנסה להוסיף משתמש חדש, אך החשבון "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" כבר קיים במכשיר זה. להמשיך בכל זאת?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" מנסה להוסיף משתמש חדש לחשבון "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". להמשיך?"</string>
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 39ceae5..35dbd24 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"バグレポート"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"バグレポートを取得"</string>
     <string name="bugreport_message" msgid="398447048750350456">"現在の端末の状態に関する情報が収集され、その内容がメールで送信されます。バグレポートが開始してから送信可能な状態となるまでには多少の時間がかかりますのでご了承ください。"</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"マナーモード"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"サウンドOFF"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"サウンドON"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"タップしてその他のオプションを表示"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USBデバッグが接続されました"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"タップしてUSBデバッグを無効化"</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"管理者とバグレポートを共有しますか?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IT 管理者からトラブルシューティングに役立てるためバグレポートを共有するようリクエストがありました"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"同意する"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"同意しない"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"バグレポートを取得しています…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"キャンセルするにはタップしてください"</string>
     <string name="select_input_method" msgid="8547250819326693584">"キーボードの変更"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"キーボードの選択"</string>
     <string name="show_ime" msgid="9157568568695230830">"スクリーンキーボードを表示する"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"その他"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"このような通知の重要度を設定します。"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"関係するユーザーのため、この設定は重要です。"</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" で新しいユーザーを追加しようとしていますが、現在この操作は禁止されています。"</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" で新しいユーザーを追加しようとしていますが、ユーザー数の上限に達しています。"</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" で新しいユーザーを追加しようとしていますが、アカウント "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" は既にこの端末に存在します。続行しますか?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" でアカウント "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" に新しいユーザーを追加しようとしています。続行しますか?"</string>
 </resources>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index b89f1f8..864e495 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"ხარვეზის შესახებ ანგარიში"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"შექმენით შეცდომის ანგარიში"</string>
     <string name="bugreport_message" msgid="398447048750350456">"იგი შეაგროვებს ინფორმაციას თქვენი მოწყობილობის ამჟამინდელი მდგომარეობის შესახებ, რათა ის ელფოსტის შეტყობინების სახით გააგზავნოს. ხარვეზის ანგარიშის მომზადებასა და შეტყობინების გაგზავნას გარკვეული დრო სჭირდება. გთხოვთ, მოითმინოთ."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"ჩუმი რეჟიმი"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ხმა გამორთულია"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ხმა ჩართულია"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"შეეხეთ დამატებითი პარამეტრებისთვის."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB გამართვა შეერთებულია"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"შეეხეთ, რათა შეწყვიტოთ USB-ის გამართვა."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"გსურთ ხარვეზის შესახებ ანგარიშის ადმინისტრატორთან გაზიარება?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"პრობლემის აღმოფხვრაში დასახმარებლად, თქვენი IT ადმინისტრატორი ხარვეზის შესახებ ანგარიშს ითხოვს."</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"მიღება"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"უარყოფა"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"მიმდინარეობს ხარვეზის შესახებ ანგარიშის შექმნა…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"შეეხეთ გასაუქმებლად"</string>
     <string name="select_input_method" msgid="8547250819326693584">"კლავიატურის შეცვლა"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"კლავიატურების არჩევა"</string>
     <string name="show_ime" msgid="9157568568695230830">"შეყვანის მეთოდის ჩვენება"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"სხვადასხვა"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"ამ შეტყობინებების მნიშვნელობის დონე განისაზღვრება თქვენ მიერ."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"მნიშვნელოვანია ჩართული მომხმარებლების გამო."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ახალი მომხმარებლის დამატებას ცდილობს, მაგრამ ამჟამად ეს მას ეკრძალება."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ახალი მომხმარებლის დამატებას ცდილობს, მაგრამ მიღწეულია მომხმარებლების ლიმიტი."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ახალი მომხმარებლის დამატებას ცდილობს, მაგრამ ანგარიში — "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" უკვე არსებობს ამ მოწყობილობაში. მაინც გსურთ გაგრძელება?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ცდილობს, ანგარიშს — "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ახალი მომხმარებელი დაუმატოს. გსურთ გაგრძელება?"</string>
 </resources>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index cc549cc..8062208 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Вирус туралы хабарлау"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Қате туралы есеп құру"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Құрылғының қазіргі күйі туралы ақпаратты жинап, электрондық хабармен жібереді. Есеп әзір болғанша біраз уақыт кетеді, шыдай тұрыңыз."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Үнсіз режимі"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Дыбыс ӨШІРУЛІ"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Дыбыс ҚОСУЛЫ"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Қосымша параметрлер үшін түртіңіз."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB жөндеу қосылған"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB жөндеуді өшіру үшін түртіңіз."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Қате туралы есепті әкімшімен бөлісу керек пе?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"АТ әкімшісі ақауларды жоюға көмектесу үшін қате туралы есепті сұрады"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ҚАБЫЛДАУ"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ҚАБЫЛДАМАУ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Қате туралы есеп құрылуда…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Бас тарту үшін түртіңіз"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Пернетақтаны өзгерту"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Пернетақталарды таңдау"</string>
     <string name="show_ime" msgid="9157568568695230830">"Енгізу әдісін көрсету"</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 6a2670c..db743b5 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"របាយការណ៍​កំហុស"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"យក​របាយការណ៍​កំហុស"</string>
     <string name="bugreport_message" msgid="398447048750350456">"វា​នឹង​​ប្រមូល​ព័ត៌មាន​អំពី​ស្ថានភាព​ឧបករណ៍​របស់​អ្នក ដើម្បី​ផ្ញើ​ជា​សារ​អ៊ីមែល។ វា​នឹង​ចំណាយ​ពេល​តិច​ពី​ពេល​ចាប់ផ្ដើម​របាយការណ៍​រហូត​ដល់​ពេល​វា​រួចរាល់​ដើម្បី​ផ្ញើ សូម​អត់ធ្មត់។"</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"របៀប​ស្ងាត់"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"បិទ​សំឡេង"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"បើក​សំឡេង"</string>
@@ -1034,18 +1043,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"ប៉ះដើម្បីបានជម្រើសថែមទៀត។"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"បាន​ភ្ជាប់​ការ​កែ​កំហុស​យូអេសប៊ី"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"ប៉ះ ដើម្បី​បិទ​ការ​កែ​កំហុស​យូអេសប៊ី។"</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"ចែករំលែករបាយការណ៍កំហុសជាមួយអ្នកគ្រប់គ្រងឬ?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"អ្នកគ្រប់គ្រងព័ត៌មានវិទ្យារបស់អ្នកបានស្នើរបាយការណ៍កំហុសដើម្បីជួយដោះស្រាយបញ្ហា"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ព្រមទទួល"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"បដិសេធ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"ទទួលយករបាយការណ៍កំហុស…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"ប៉ះដើម្បីបោះបង់"</string>
     <string name="select_input_method" msgid="8547250819326693584">"ប្ដូរ​ក្ដារចុច"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"ជ្រើស​ក្ដារចុច"</string>
     <string name="show_ime" msgid="9157568568695230830">"បង្ហាញ​វិធី​សាស្ត្រ​បញ្ចូល"</string>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index 07cd62d..cde0901 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"ದೋಷದ ವರದಿ"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"ದೋಷ ವರದಿ ರಚಿಸಿ"</string>
     <string name="bugreport_message" msgid="398447048750350456">"ನಿಮ್ಮ ಸಾಧನದ ಪ್ರಸ್ತುತ ಸ್ಥಿತಿಯ ಕುರಿತು ಮಾಹಿತಿಯನ್ನು ಸಂಗ್ರಹಿಸಿಕೊಳ್ಳುವುದರ ಜೊತೆ ಇ-ಮೇಲ್ ರೂಪದಲ್ಲಿ ನಿಮಗೆ ರವಾನಿಸುತ್ತದೆ. ಇದು ದೋಷ ವರದಿಯನ್ನು ಪ್ರಾರಂಭಿಸಿದ ಸಮಯದಿಂದ ಅದನ್ನು ಕಳುಹಿಸುವವರೆಗೆ ಸ್ವಲ್ಪ ಸಮಯವನ್ನು ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ; ದಯವಿಟ್ಟು ತಾಳ್ಮೆಯಿಂದಿರಿ."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"ಶಾಂತ ಮೋಡ್"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ಶಬ್ಧ ಆಫ್ ಆಗಿದೆ"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ಶಬ್ಧ ಆನ್ ಆಗಿದೆ"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳಿಗೆ ಸ್ಪರ್ಶಿಸಿ."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ಡೀಬಗಿಂಗ್‌‌ ಸಂಪರ್ಕ"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ಡೀಬಗಿಂಗ್‌ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಸ್ಪರ್ಶಿಸಿ."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"ದೋಷ ವರದಿಯನ್ನು ನಿರ್ವಾಹಕರ ಜೊತೆಗೆ ಹಂಚಿಕೊಳ್ಳುವುದೇ?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"ನಿಮ್ಮ ಐಟಿ ನಿರ್ವಾಹಕರು ಸಮಸ್ಯೆ ನಿವಾರಣೆಗೆ ಸಹಾಯ ಮಾಡಲು ದೋಷ ವರದಿಯನ್ನು ಮನವಿ ಮಾಡಿದ್ದಾರೆ"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ಸಮ್ಮತಿಸು"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ತಿರಸ್ಕರಿಸು"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"ದೋಷದ ವರದಿಯನ್ನು ತೆಗೆದುಕೊಳ್ಳಲಾಗುತ್ತಿದೆ…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"ರದ್ದುಗೊಳಿಸಲು ಸ್ಪರ್ಶಿಸಿ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"ಕೀಬೋರ್ಡ್ ಬದಲಿಸಿ"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"ಕೀಬೋರ್ಡ್‌ಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
     <string name="show_ime" msgid="9157568568695230830">"ಇನ್‌ಪುಟ್‌ ವಿಧಾನವನ್ನು ತೋರಿಸು"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 203661c..f3c6c69 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"버그 신고"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"버그 신고"</string>
     <string name="bugreport_message" msgid="398447048750350456">"현재 기기 상태에 대한 정보를 수집하여 이메일 메시지로 전송합니다. 버그 신고를 시작하여 전송할 준비가 되려면 약간 시간이 걸립니다."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"무음 모드"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"소리 꺼짐"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"소리 켜짐"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"더 많은 옵션을 확인하려면 터치하세요."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB 디버깅 연결됨"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB 디버깅을 사용하지 않으려면 터치하세요."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"관리자와 버그 보고서를 공유하시겠습니까?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IT 관리자가 문제해결을 위해 버그 보고서를 요청했습니다."</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"수락"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"거절"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"버그 보고서 가져오는 중..."</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"취소하려면 터치하세요."</string>
     <string name="select_input_method" msgid="8547250819326693584">"키보드 변경"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"키보드 선택"</string>
     <string name="show_ime" msgid="9157568568695230830">"입력 방법 표시"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"기타"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"이러한 알림의 중요도를 설정했습니다."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"관련된 사용자가 있으므로 중요합니다."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>"에서 새 사용자를 추가하려고 하지만 현재 금지되어 있습니다."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>"에서 새 사용자를 추가하려고 하지만 사용자 한도에 도달했습니다."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>"에서 새 사용자를 추가하려고 하지만 계정 "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>"이(가) 이미 기기에 있습니다. 계속할까요?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>"에서 계정 "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>"에 새 사용자를 추가하려고 합니다. 계속할까요?"</string>
 </resources>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index c67aef8..58402e9 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Ката тууралуу билдирүү"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Ката тууралуу билдирүү түзүү"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Бул сиздин түзмөгүңүздүн учурдагы абалын эмейл билдирүүсү катары жөнөтүш максатында маалымат чогултат. Ката тууралуу билдирүү түзүлүп башталып, жөнөтүлгөнгө чейин бир аз убакыт керек болот; сураныч, бир аз күтө туруңуз."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Үнсүз режим"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Добушу ӨЧҮК"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Добушу КҮЙҮК"</string>
@@ -1033,18 +1042,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Көбүрөөк параметр үчүн тийип коюңуз."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB мүчүлүштүктөрдү оңдоо туташтырылган"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB мүчүлүштүктөрдү жоюу мүмкүнчүлүгүн өчүрүү үчүн тийип коюңуз."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Администратор менен мүчүлүштүктөр тууралуу кабар бөлүшүлсүнбү?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IT администраторуңуз бузулууларды аныктап оңдоого жардам берүү үчүн мүчүлүштүктөр тууралу кабар берүүнү суранды"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"КАБЫЛ АЛУУ"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ЧЕТКЕ КАГУУ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Мүчүлүштүк тууралуу кабар алынууда…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Жокко чыгаруу үчүн тийип коюңуз"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Баскычтопту өзгөртүү"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Баскычтопторду тандаңыз"</string>
     <string name="show_ime" msgid="9157568568695230830">"Киргизүү ыкмасын көрсөтүү"</string>
@@ -1525,12 +1528,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Калган-каткандар"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Бул эскертмелердин маанилүүлүгүн белгиледиңиз."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Булар сиз үчүн маанилүү адамдар."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" жаңы колдонуучу кошууга аракет кылууда, бирок учурда ага тыюу салынган."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" жаңы колдонуучу кошууга аракет кылууда, бирок колдонуучулар чегине жетип калды."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" жаңы колдонуучу кошууга аракет кылууда, бирок "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" каттоо эсеби мурунтан эле бул түзмөктө бар. Баары бир уланта берсинби?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" жаңы колдонуучуну "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" каттоо эсебине кошууга аракет кылууда. Улантылсынбы?"</string>
 </resources>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index dab801c..94897ac 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"ລາຍງານຂໍ້ຜິດພາດ"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"ໃຊ້ລາຍງານຂໍ້ບົກພ່ອງ"</string>
     <string name="bugreport_message" msgid="398447048750350456">"ນີ້ຈະເປັນການເກັບກຳຂໍ້ມູນກ່ຽວກັບ ສະຖານະປັດຈຸບັນຂອງອຸປະກອນທ່ານ ເພື່ອສົ່ງເປັນຂໍ້ຄວາມທາງອີເມວ. ມັນຈະໃຊ້ເວລາໜ້ອຍນຶ່ງ ໃນການເລີ່ມຕົ້ນການລາຍງານຂໍ້ຜິດພາດ ຈົນກວ່າຈະພ້ອມທີ່ຈະສົ່ງໄດ້, ກະລຸນາລໍຖ້າ."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"ໂໝດປິດສຽງ"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ປິດສຽງແລ້ວ"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ເປິດສຽງແລ້ວ"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"ສຳ​ພັດ​ສຳ​ລັບ​ທາງ​ເລືອກ​ເພີ່ມ​ເຕີມ."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"ເຊື່ອມຕໍ່ການດີບັ໊ກຜ່ານ USB ແລ້ວ"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"ແຕະເພື່ອປິດການດີບັ໊ກຜ່ານ USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"ແບ່ງປັນລາຍງານຂໍ້ຜິດພາດກັບຜູ້ເບິ່ງແຍງລະບົບບໍ?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"ຜູ້ເບິ່ງແຍງລະບົບໄອທີຂອງທ່ານໄດ້ຮ້ອງຂໍເອົາລາຍງານຂໍ້ຜິດພາດເພື່ອຊ່ວຍແກ້ໄຂບັນຫາ"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ຍອມຮັບ"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ປະຕິເສດ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"ກຳລັງເອົາລາຍງານຂໍ້ຜິດພາດ…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"ແຕະເພື່ອຍົກເລີກ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"​ປ່ຽນ​ແປ້ນ​ພິມ"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"​ເລືອກ​ແປ້ນ​ພິມ"</string>
     <string name="show_ime" msgid="9157568568695230830">"​ສະ​ແດງ​ຮູບ​ແບບ​ການ​ປ້ອນ​ຂໍ້​ມູນ"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"ອື່ນໆ"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"ທ່ານຕັ້ງຄວາມສຳຄັນຂອງການແຈ້ງເຕືອນເຫຼົ່ານີ້."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"ຂໍ້ຄວາມນີ້ສຳຄັນເນື່ອງຈາກບຸກຄົນທີ່ກ່ຽວຂ້ອງ."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ກຳລັງພະຍາຍາມເພີ່ມຜູ້ໃຊ້ໃໝ່, ແຕ່ຖືກຫ້າມໃນຂະນະນີ້."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ກຳລັງພະຍາຍາມເພີ່ມຜູ້ໃຊ້ໃໝ່, ແຕ່ໄດ້ຮອດຂີດຈຳກັດຜູ້ໃຊ້ແລ້ວ."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ກຳລັງພະຍາຍາມເພີ່ມຜູ້ໃຊ້ໃໝ່, ແຕ່ບັນຊີ "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ມີຢູ່ແລ້ວໃນອຸປະກອນນີ້. ແນວໃດກໍດຳເນີນຕໍ່ບໍ?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ກຳລັງພະຍາຍາມເພີ່ມຜູ້ໃຊ້ໃໝ່ສຳລັບບັນຊີ "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". ດຳເນີນຕໍ່ບໍ?"</string>
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 74f34c0f..5da0a81 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -213,6 +213,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Pranešimas apie riktą"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Pranešti apie riktą"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Bus surinkta informacija apie dabartinę įrenginio būseną ir išsiųsta el. pašto pranešimu. Šiek tiek užtruks, kol pranešimas apie riktą bus paruoštas siųsti; būkite kantrūs."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Tylus režimas"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Garsas IŠJUNGTAS"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Garsas ĮJUNGTAS"</string>
@@ -1046,18 +1055,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Palieskite, kad būtų rodoma daugiau parinkčių."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB derinimas prijungtas"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Neleisti USB derinimo."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Bendrinti pranešimą apie riktą su administratoriumi?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Jūsų IT administratorius pateikė pranešimo apie riktą užklausą, kad galėtų padėti pašalinti triktis"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"SUTIKTI"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ATMESTI"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Pateikiamas pranešimas apie riktą…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Palieskite, kad atšauktumėte"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Klaviatūros keitimas"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Pasirinkti klaviatūras"</string>
     <string name="show_ime" msgid="9157568568695230830">"Rodyti įvesties metodą"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 25b80b2..86d6600 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -212,6 +212,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Kļūdu ziņojums"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Kļūdu ziņojuma sagatavošana"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Veicot šo darbību, tiks apkopota informācija par jūsu ierīces pašreizējo stāvokli un nosūtīta e-pasta ziņojuma veidā. Kļūdu ziņojuma pabeigšanai un nosūtīšanai var būt nepieciešams laiks. Lūdzu, esiet pacietīgs."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Klusuma režīms"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Skaņa ir IZSLĒGTA."</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Skaņa ir IESLĒGTA."</string>
@@ -1039,18 +1048,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Citas opcijas"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB atkļūdošana ir pievienota."</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Iespējot USB atkļūdošanu."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Vai kopīgot kļūdas pārskatu ar administratoru?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Jūsu IT administrators pieprasīja kļūdas pārskatu, lai palīdzētu novērst problēmu."</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"APSTIPRINĀT"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"NORAIDĪT"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Notiek kļūdas pārskata izveide…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Pieskarieties, lai atceltu"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Tastatūras maiņa"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Izvēlēties tastatūru"</string>
     <string name="show_ime" msgid="9157568568695230830">"Rādīt ievades metodi"</string>
@@ -1542,12 +1545,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Dažādi"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Jūs iestatījāt šo paziņojumu svarīguma līmeni."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Tas ir svarīgi iesaistīto personu dēļ."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" mēģina pievienot jaunu lietotāju, taču pašlaik tas ir aizliegts."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" mēģina pievienot jaunu lietotāju, taču ir sasniegts lietotāju skaita ierobežojums."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" mēģina pievienot jaunu lietotāju, taču šajā ierīcē jau ir izveidots konts "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Vai turpināt?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" mēģina pievienot jaunu lietotāju kontam "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Vai turpināt?"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc160-am/strings.xml b/core/res/res/values-mcc310-mnc160-am/strings.xml
index 86b0651..5a6635c 100644
--- a/core/res/res/values-mcc310-mnc160-am/strings.xml
+++ b/core/res/res/values-mcc310-mnc160-am/strings.xml
@@ -23,7 +23,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="3017901214286816293">"በWi-Fi ላይ ጥሪዎችን ለማድረግ እና መልዕክቶችን ለመላክ መጀመሪያ የአገልግሎት አቅራቢዎ ይህን አገልግሎት እንዲያዘጋጅልዎ መጠየቅ አለብዎት። ከዚያ ከቅንብሮች ሆነው እንደገና የWi-Fi ጥሪን ያብሩ።"</item>
+    <item msgid="3017901214286816293">"በWi-Fi ላይ ጥሪዎችን ለማድረግ እና መልዕክቶችን ለመላክ መጀመሪያ የአገልግሎት አቅራቢዎ ይህን አገልግሎት እንዲያዘጋጅልዎ ይጠይቁ። ከዚያ ከቅንብሮች ሆነው እንደገና የWi-Fi ጥሪን ያብሩ።"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7068215934335709161">"የአገልግሎት አቅራቢዎ ጋር ይመዝገቡ"</item>
diff --git a/core/res/res/values-mcc310-mnc160-ca/strings.xml b/core/res/res/values-mcc310-mnc160-ca/strings.xml
index 5a989bf..89baf1b 100644
--- a/core/res/res/values-mcc310-mnc160-ca/strings.xml
+++ b/core/res/res/values-mcc310-mnc160-ca/strings.xml
@@ -28,5 +28,5 @@
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7068215934335709161">"Registra\'t amb el teu operador de telefonia mòbil"</item>
   </string-array>
-    <string name="wfcSpnFormat" msgid="2031160810542298336">"Trucada de Wi-Fi de: %s"</string>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Trucada per Wi-Fi amb %s"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc160-et-rEE/strings.xml b/core/res/res/values-mcc310-mnc160-et-rEE/strings.xml
index f625e50..c3be115 100644
--- a/core/res/res/values-mcc310-mnc160-et-rEE/strings.xml
+++ b/core/res/res/values-mcc310-mnc160-et-rEE/strings.xml
@@ -23,10 +23,10 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="3017901214286816293">"Üle WiFi-võrgu helistamiseks ja sõnumite saatmiseks paluge operaatoril esmalt see teenus seadistada. Seejärel lülitage WiFi-kõned menüüs Seaded uuesti sisse."</item>
+    <item msgid="3017901214286816293">"WiFi-võrgu kaudu helistamiseks ja sõnumite saatmiseks paluge operaatoril esmalt see teenus seadistada. Seejärel lülitage WiFi-kõned menüüs Seaded uuesti sisse."</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7068215934335709161">"Registreeruge operaatori juures"</item>
   </string-array>
-    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s WiFi kaudu helistamine"</string>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Operaatori %s WiFi-kõned"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc160-gl-rES/strings.xml b/core/res/res/values-mcc310-mnc160-gl-rES/strings.xml
index 0d85bb87..f02d667 100644
--- a/core/res/res/values-mcc310-mnc160-gl-rES/strings.xml
+++ b/core/res/res/values-mcc310-mnc160-gl-rES/strings.xml
@@ -23,10 +23,10 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="3017901214286816293">"Para facer chamadas e enviar mensaxes a través da wifi, primeiro pídelle ao teu operador que configure este servizo. A continuación, activa de novo as chamadas wifi en Configuración."</item>
+    <item msgid="3017901214286816293">"Para facer chamadas e enviar mensaxes a través da wifi, primeiro pídelle ao teu operador que configure este servizo. A continuación, activa de novo as chamadas por wifi en Configuración."</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7068215934335709161">"Rexístrate co teu operador"</item>
   </string-array>
-    <string name="wfcSpnFormat" msgid="2031160810542298336">"Chamadas wifi de %s"</string>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Chamadas por wifi de %s"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc160-hu/strings.xml b/core/res/res/values-mcc310-mnc160-hu/strings.xml
index a42073f..7dbf9e8 100644
--- a/core/res/res/values-mcc310-mnc160-hu/strings.xml
+++ b/core/res/res/values-mcc310-mnc160-hu/strings.xml
@@ -23,10 +23,10 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="3017901214286816293">"Ha Wi-Fi-n szeretne telefonálni és üzenetet küldeni, kérje meg szolgáltatóját, hogy állítsa be ezt a szolgáltatást. Ezután a Beállítások menüben kapcsolhatja be újra a Wi-Fi-hívást."</item>
+    <item msgid="3017901214286816293">"Ha Wi-Fin szeretne telefonálni és üzenetet küldeni, kérje meg szolgáltatóját, hogy állítsa be ezt a szolgáltatást. Ezután a Beállítások menüben kapcsolhatja be újra a Wi-Fi-hívást."</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="7068215934335709161">"Regisztráljon a szolgáltatójánál"</item>
+    <item msgid="7068215934335709161">"Regisztráljon szolgáltatójánál"</item>
   </string-array>
     <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi-hívás"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc160-it/strings.xml b/core/res/res/values-mcc310-mnc160-it/strings.xml
index 7403ef7..d8479d3 100644
--- a/core/res/res/values-mcc310-mnc160-it/strings.xml
+++ b/core/res/res/values-mcc310-mnc160-it/strings.xml
@@ -23,10 +23,10 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="3017901214286816293">"Per effettuare chiamate e inviare messaggi tramite Wi-Fi, è necessario prima chiedere all\'operatore telefonico di attivare il servizio. Successivamente, riattiva le chiamate Wi-Fi dalle Impostazioni."</item>
+    <item msgid="3017901214286816293">"Per poter effettuare chiamate e inviare messaggi tramite Wi-Fi, devi chiedere all\'operatore di attivare il servizio. Dopodiché, riattiva le chiamate Wi-Fi dalle Impostazioni."</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7068215934335709161">"Registrati con il tuo operatore"</item>
   </string-array>
-    <string name="wfcSpnFormat" msgid="2031160810542298336">"Chiamata Wi-Fi %s"</string>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Chiamate Wi-Fi %s"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc160-ky-rKG/strings.xml b/core/res/res/values-mcc310-mnc160-ky-rKG/strings.xml
index c160012..8b88ac1 100644
--- a/core/res/res/values-mcc310-mnc160-ky-rKG/strings.xml
+++ b/core/res/res/values-mcc310-mnc160-ky-rKG/strings.xml
@@ -23,10 +23,10 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="3017901214286816293">"Wi-Fi аркылуу чалууларды аткарып жана билдирүүлөрдү жөнөтүү үчүн адегенде операторуңуздан бул кызматты орнотушун сураныңыз. Андан соң, Жөндөөлөрдөн Wi-Fi чалууну кайра күйгүзүңүз."</item>
+    <item msgid="3017901214286816293">"Wi-Fi аркылуу чалууларды аткарып жана билдирүүлөрдү жөнөтүү үчүн адегенде байланыш операторуңуздан бул кызматты орнотушун сураныңыз. Андан соң, Жөндөөлөрдөн Wi-Fi чалууну кайра күйгүзүңүз."</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7068215934335709161">"Операторуңузга катталыңыз"</item>
   </string-array>
-    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi Чалуу"</string>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi чалуу"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc160-ms-rMY/strings.xml b/core/res/res/values-mcc310-mnc160-ms-rMY/strings.xml
index 1fe0157..74bd9d6 100644
--- a/core/res/res/values-mcc310-mnc160-ms-rMY/strings.xml
+++ b/core/res/res/values-mcc310-mnc160-ms-rMY/strings.xml
@@ -23,10 +23,10 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="3017901214286816293">"Untuk membuat panggilan dan menghantar mesej melalui Wi-Fi, mula-mula minta pembawa anda untuk menyediakan perkhidmatan ini. Kemudian hidupkan panggilan Wi-Fi semula daripada Tetapan."</item>
+    <item msgid="3017901214286816293">"Untuk membuat panggilan dan menghantar mesej melalui Wi-Fi, mula-mula minta pembawa anda menyediakan perkhidmatan ini. Kemudian hidupkan panggilan Wi-Fi sekali lagi daripada Tetapan."</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7068215934335709161">"Daftar dengan pembawa anda"</item>
   </string-array>
-    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Panggilan Wi-Fi"</string>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Panggilan Wi-Fi %s"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc160-ne-rNP/strings.xml b/core/res/res/values-mcc310-mnc160-ne-rNP/strings.xml
index f248fb7..8956249 100644
--- a/core/res/res/values-mcc310-mnc160-ne-rNP/strings.xml
+++ b/core/res/res/values-mcc310-mnc160-ne-rNP/strings.xml
@@ -26,7 +26,7 @@
     <item msgid="3017901214286816293">"Wi-Fi बाट कल गर्न र सन्देशहरू पठाउन, सबभन्दा पहिला यो सेवा सेटअप गर्न तपाईँको वाहकलाई भन्नुहोस्। त्यसपछि फेरि सेटिङहरूबाट Wi-Fi कलिङ सक्रिय पार्नुहोस्।"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="7068215934335709161">"तपाईँको वाहकसँग दर्ता गर्नुहोस्"</item>
+    <item msgid="7068215934335709161">"आफ्नो वाहकसँग दर्ता गर्नुहोस्"</item>
   </string-array>
     <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi कलिङ"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc160-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc160-pt-rPT/strings.xml
index 93b04ee..86dba8c 100644
--- a/core/res/res/values-mcc310-mnc160-pt-rPT/strings.xml
+++ b/core/res/res/values-mcc310-mnc160-pt-rPT/strings.xml
@@ -23,10 +23,10 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="3017901214286816293">"Para fazer chamadas e enviar mensagens por Wi-Fi, comece por pedir ao seu operador para configurar este serviço. Em seguida, nas Definições, ative novamente as chamadas por Wi-Fi."</item>
+    <item msgid="3017901214286816293">"Para fazer chamadas e enviar mensagens por Wi-Fi, comece por pedir ao seu operador para configurar este serviço. Em seguida, nas Definições, ative novamente as Chamadas Wi-Fi."</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7068215934335709161">"Registar-se junto do seu operador"</item>
   </string-array>
-    <string name="wfcSpnFormat" msgid="2031160810542298336">"Chamadas por Wi-Fi da %s"</string>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Chamadas Wi-Fi da %s"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc160-tl/strings.xml b/core/res/res/values-mcc310-mnc160-tl/strings.xml
index 44dadd5..380b410 100644
--- a/core/res/res/values-mcc310-mnc160-tl/strings.xml
+++ b/core/res/res/values-mcc310-mnc160-tl/strings.xml
@@ -23,10 +23,10 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="3017901214286816293">"Upang tumawag at magpadala ng mga mensahe sa pamamagitan ng Wi-Fi, hilingin muna sa iyong carrier na i-set up ang serbisyong ito. Pagkatapos ay muling i-on ang pagtawag sa Wi-Fi mula sa Mga Setting."</item>
+    <item msgid="3017901214286816293">"Upang tumawag at magpadala ng mga mensahe sa pamamagitan ng Wi-Fi, hilingin muna sa iyong carrier na i-set up ang serbisyong ito. Pagkatapos ay muling i-on ang pagtawag gamit ang Wi-Fi mula sa Mga Setting."</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7068215934335709161">"Magparehistro sa iyong carrier"</item>
   </string-array>
-    <string name="wfcSpnFormat" msgid="2031160810542298336">"Pagtawag sa Pamamagitan ng Wi-Fi ng %s"</string>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Pagtawag Gamit ang Wi-Fi ng %s"</string>
 </resources>
diff --git a/core/res/res/values-mcc310-mnc160-uk/strings.xml b/core/res/res/values-mcc310-mnc160-uk/strings.xml
index 773930a..9e4d94c 100644
--- a/core/res/res/values-mcc310-mnc160-uk/strings.xml
+++ b/core/res/res/values-mcc310-mnc160-uk/strings.xml
@@ -23,7 +23,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="3017901214286816293">"Щоб телефонувати або надсилати повідомлення через Wi-Fi, спочатку попросіть свого оператора налаштувати цю послугу. Після цього ввімкніть дзвінки через Wi-Fi у налаштуваннях."</item>
+    <item msgid="3017901214286816293">"Щоб телефонувати або надсилати повідомлення через Wi-Fi, спершу попросіть свого оператора налаштувати цю послугу. Після цього ввімкніть дзвінки через Wi-Fi у налаштуваннях."</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7068215934335709161">"Зареєструйтеся в оператора"</item>
diff --git a/core/res/res/values-mcc310-mnc160-vi/strings.xml b/core/res/res/values-mcc310-mnc160-vi/strings.xml
index 253c93e..8f68be6 100644
--- a/core/res/res/values-mcc310-mnc160-vi/strings.xml
+++ b/core/res/res/values-mcc310-mnc160-vi/strings.xml
@@ -23,10 +23,10 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="3017901214286816293">"Để gọi điện và gửi tin nhắn qua Wi-Fi, trước tiên hãy yêu cầu nhà cung cấp dịch vụ của bạn thiết lập dịch vụ này. Sau đó, bật lại gọi qua Wi-Fi từ Cài đặt."</item>
+    <item msgid="3017901214286816293">"Để gọi điện và gửi tin nhắn qua Wi-Fi, trước tiên hãy yêu cầu nhà cung cấp dịch vụ của bạn thiết lập dịch vụ này. Sau đó, bật lại Gọi qua Wi-Fi từ Cài đặt."</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="7068215934335709161">"Đăng ký với nhà cung cấp dịch vụ của bạn"</item>
   </string-array>
-    <string name="wfcSpnFormat" msgid="2031160810542298336">"Gọi điện qua Wi-Fi %s"</string>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Gọi qua Wi-Fi %s"</string>
 </resources>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index dc34319..6acdb45 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Извештај за грешка"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Земи извештај за грешки"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Ова ќе собира информации за моменталната состојба на вашиот уред, за да ги испрати како порака по е-пошта. Тоа ќе одземе малку време почнувајќи од извештајот за грешки додека не се подготви за праќање; бидете трпеливи."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Тивок режим"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Звукот е исклучен"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Звукот е вклучен"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Допри за повеќе опции."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Поврзано е отстранување грешки преку УСБ"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Допрете за да се оневозможи отстранувањето грешки преку USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Да се сподели извештајот за грешки со администраторот?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Вашиот ИТ-администратор побара извештај за грешки за да помогне со отстранување на грешките"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ПРИФАТИ"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ОДБИЈ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Се зема извештајот за грешки…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Допрете за да откажете"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Измени тастатура"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Избери тастатури"</string>
     <string name="show_ime" msgid="9157568568695230830">"Прикажи влезен метод"</string>
@@ -1526,12 +1529,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Разно"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Ја поставивте важноста на известувањава."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Ова е важно заради луѓето кои се вклучени."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" се обидува да додаде нов корисник, но во моментов е забрането."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" се обидува да додаде нов корисник, но ограничувањето за корисници е достигнато."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" се обидува да додаде нов корисник, но сметката "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" веќе постои на уредот. Сепак продолжете?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" се обидува да додаде нов корисник за сметката "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Продолжете?"</string>
 </resources>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index 7580dddb..58fc6e1 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"ബഗ് റിപ്പോർട്ട്"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"ബഗ് റിപ്പോർട്ട് എടുക്കുക"</string>
     <string name="bugreport_message" msgid="398447048750350456">"ഒരു ഇമെയിൽ സന്ദേശമായി അയയ്‌ക്കുന്നതിന്, ഇത് നിങ്ങളുടെ നിലവിലെ ഉപകരണ നിലയെക്കുറിച്ചുള്ള വിവരങ്ങൾ ശേഖരിക്കും. ബഗ് റിപ്പോർട്ട് ആരംഭിക്കുന്നതിൽ നിന്ന് ഇത് അയയ്‌ക്കാനായി തയ്യാറാകുന്നതുവരെ അൽപ്പസമയമെടുക്കും; ക്ഷമയോടെ കാത്തിരിക്കുക."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"നിശബ്‌ദ മോഡ്"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ശബ്‌ദം ഓഫാണ്"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ശബ്‌ദം ഓണാണ്"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"കൂടുതൽ ഓപ്‌ഷനുകൾക്ക് സ്‌പർശിക്കൂ."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ഡീബഗ്ഗിംഗ് കണക്‌റ്റുചെയ്‌തു"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ഡീബഗ്ഗിംഗ് ഓഫാക്കാൻ സ്‌പർശിക്കൂ."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"അഡ്‌മിനുമായി ബഗ് റിപ്പോർട്ട് പങ്കിടണോ?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"പ്രശ്നം പരിഹരിക്കുന്നതിന് നിങ്ങളുടെ ഐടി അഡ്‌മിൻ ഒരു ബഗ് റിപ്പോർട്ട് അഭ്യർത്ഥിച്ചു"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"അംഗീകരിക്കുക"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"നിരസിക്കുക"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"ബഗ് റിപ്പോർട്ട് എടുക്കുന്നു…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"റദ്ദാക്കുന്നതിന് സ്പർശിക്കുക"</string>
     <string name="select_input_method" msgid="8547250819326693584">"കീബോഡ് മാറ്റുക"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"കീബോർഡുകൾ തിരഞ്ഞെടുക്കുക"</string>
     <string name="show_ime" msgid="9157568568695230830">"ടൈപ്പുചെയ്യൽ രീതി കാണിക്കുക"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"പലവക"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"ഈ അറിയിപ്പുകളുടെ പ്രാധാന്യം നിങ്ങൾ സജ്ജീകരിച്ചു."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"ഉൾപ്പെട്ടിട്ടുള്ള ആളുകളെ കണക്കിലെടുക്കുമ്പോള്‍ ഇത് പ്രധാനപ്പെട്ടതാണ്‌."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315">"പുതിയൊരു ഉപയോക്താവിനെ ചേർക്കാൻ "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ശ്രമിക്കുന്നു, എന്നാലിത് നിലവിൽ നിരോധിക്കപ്പെട്ടിരിക്കുന്നു."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266">"പുതിയൊരു ഉപയോക്താവിനെ ചേർക്കാൻ "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ശ്രമിക്കുന്നു, എന്നാൽ ഉപയോക്തൃ പരിധി എത്തിക്കഴിഞ്ഞിരിക്കുന്നു."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789">"പുതിയൊരു ഉപയോക്താവിനെ ചേർക്കാൻ "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ശ്രമിക്കുന്നു, എന്നാൽ "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" എന്ന അക്കൗണ്ട് ഇതിനകം തന്നെ ഈ ഉപകരണത്തിൽ നിലവിലുണ്ട്. എന്തായാലും തുടരണോ?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" എന്ന അക്കൗണ്ടിനായി പുതിയൊരു ഉപയോക്താവിനെ ചേർക്കാൻ "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ശ്രമിക്കുന്നു. തുടരണോ?"</string>
 </resources>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index f49dd99..b59863b 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Алдаа мэдээллэх"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Согог репорт авах"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Энэ таны төхөөрөмжийн одоогийн статусын талаарх мэдээллийг цуглуулах ба имэйл мессеж болгон илгээнэ. Алдааны мэдэгдлээс эхэлж илгээхэд бэлэн болоход хэсэг хугацаа зарцуулагдана тэвчээртэй байна уу."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Чимээгүй горим"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Дуу хаагдсан"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Дуу асав"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Нэмэлт сонголтыг харахын тулд дарна."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB дебаг холбогдсон"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB дебагийг идэвхгүй болгох бол хүрнэ үү."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Алдааны тайланг админтай хуваалцах уу?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Асуудлыг шийдвэрлэхийн таны МТ админтулд алдааны тайланг хүслээ"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ЗӨВШӨӨРӨХ"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ТАТГАЛЗАХ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Алдааны тайланг авч байна..."</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Цуцлахын тулд хүрэх"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Гарыг өөрчлөх"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Гар сонгох"</string>
     <string name="show_ime" msgid="9157568568695230830">"Оруулах аргыг харуулах"</string>
@@ -1522,12 +1525,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Бусад"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Та эдгээр мэдэгдлийн ач холбогдлыг тогтоосон."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Оролцсон хүмүүсээс шалтгаалан энэ нь өндөр ач холбогдолтой."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" шинэ хэрэглэгч нэмэхээр оролдож байгаа боловч одоогоор боломжгүй байна."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" шинэ хэрэглэгч нэмэхээр оролдож байгаа ч хэрэглэгчийн тооны хязгаарт хүрсэн байна."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" шинэ хэрэглэгч нэмэх гэсэн боловч "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" бүртгэл нь энэ төхөөрөмжид аль хэдийн байна. Гэсэн хэдий ч үргэлжлүүлэх үү?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" нь "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" бүртгэлд шинэ хэрэглэгч нэмэх гэж байна. Үргэлжлүүлэх үү?"</string>
 </resources>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 9ddd023..bf52c38 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"दोष अहवाल"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"दोष अहवाल घ्या"</string>
     <string name="bugreport_message" msgid="398447048750350456">"ई-मेल संदेश म्हणून पाठविण्यासाठी, हे आपल्या वर्तमान डिव्हाइस स्थितीविषयी माहिती संकलित करेल. दोष अहवाल प्रारंभ करण्यापासून तो पाठविण्यापर्यंत थोडा वेळ लागेल; कृपया धीर धरा."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"मूक मोड"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ध्वनी बंद आहे"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ध्वनी चालू आहे"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"अधिक पर्यायांसाठी स्पर्श करा."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डीबग करणे कनेक्‍ट केले"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB डीबग करणे अक्षम करण्यासाठी स्पर्श करा."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"प्रशासकासह दोष अहवाल सामायिक करायचा?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"आपल्या IT प्रशासकाने समस्या निवारण करण्‍यात मदत करण्यासाठी दोष अहवालाची विनंती केली"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"स्वीकार करा"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"नकार द्या"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"दोष अहवाल घेत आहे..."</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"रद्द करण्यासाठी स्पर्श करा"</string>
     <string name="select_input_method" msgid="8547250819326693584">"कीबोर्ड बदला"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"कीबोर्ड निवडा"</string>
     <string name="show_ime" msgid="9157568568695230830">"इनपुट पद्धत दर्शवा"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"संकीर्ण"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"आपण या सूचनांचे महत्त्व सेट केले."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"सामील असलेल्या लोकांमुळे हे महत्वाचे आहे."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" नवीन वापरकर्ता जोडण्याचा प्रयत्न करीत आहे परंतु तो सध्‍या प्रतिबंधित आहे."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" नवीन वापरकर्ता जोडण्यासाठी प्रयत्न करीत आहे परंतु वापरकर्ता मर्यादा गाठली गेली आहे."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" नवीन वापरकर्ता जोडण्‍याचा प्रयत्न करीत आहे परंतु या डिव्‍हाइसवर "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" खाते आधीपासून अस्तित्वात आहे. तरीही पुढे सुरु ठेवायचे?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" खात्यासाठी "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" नवीन वापरकर्ता जोडण्याचा प्रयत्न करीत आहे. पुढे सुरु ठेवायचे?"</string>
 </resources>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 0da5820..eaa3dcf 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Laporan pepijat"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Ambil laporan pepijat"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Ini akan mengumpul maklumat tentang keadaan peranti semasa anda untuk dihantarkan sebagai mesej e-mel. Harap bersabar, mungkin perlu sedikit masa untuk memulakan laporan sehingga siap untuk dihantar."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mod senyap"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Bunyi DIMATIKAN"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Bunyi DIHIDUPKAN"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Sentuh untuk mendapatkan lagi pilihan."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Penyahpepijatan USB disambungkan"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Sentuh untuk melumpuhkan penyahpepijatan USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Kongsi laporan pepijat dengan pentadbir?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Pentadbir IT anda meminta laporan pepijat untuk membantu menyelesaikan masalah"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"TERIMA"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"TOLAK"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Mengambil laporan pepijat…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Sentuh untuk membatalkan"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Tukar papan kekunci"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Pilih papan kekunci"</string>
     <string name="show_ime" msgid="9157568568695230830">"Tunjukkan kaedah input"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Pelbagai"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Anda menetapkan kepentingan pemberitahuan ini."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Mesej ini penting disebabkan orang yang terlibat."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" cuba menambahkan pengguna baharu tetapi dilarang pada masa ini."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" cuba menambahkan pengguna baharu tetapi had pengguna telah dicapai."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" cuba menambahkan pengguna baharu tetapi akaun "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" telah wujud pada peranti ini. Teruskan juga?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" cuba menambahkan pengguna baharu untuk akaun "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Teruskan?"</string>
 </resources>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index 63dea2d..c980731 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"အမှားရှာဖွေပြင်ဆင်မှုမှတ်တမ်း"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"အမှားရှာဖွေပြင်ဆင်မှုမှတ်တမ်းအား ယူရန်"</string>
     <string name="bugreport_message" msgid="398447048750350456">"သင့်ရဲ့ လက်ရှိ စက်အခြေအနေ အချက်အလက်များကို အီးမေးလ် အနေဖြင့် ပေးပို့ရန် စုဆောင်းပါမည်။ အမှားရှာဖွေပြင်ဆင်မှုမှတ်တမ်းမှ ပေးပို့ရန် အသင့်ဖြစ်သည်အထိ အချိန် အနည်းငယ်ကြာမြင့်မှာ ဖြစ်သဖြင့် သည်းခံပြီး စောင့်ပါရန်"</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"အသံတိတ်စနစ်"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"အသံပိတ်ထားသည်"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"အသံဖွင့်ထားသည်"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"ထပ်မံရွေးချယ်စရာများအတွက် ထိပါ"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB အမှားစစ်ခြင်းအား ချိတ်ဆက်ထားသည်"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ဒီဘာဂင် ပိတ်ရန် ထိပါ။"</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"ချွတ်ယွင်းချက် အစီရင်ခံစာကို စီမံအုပ်ချုပ်သူထံ ပို့မလား။"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"သင်၏ IT စီမံအုပ်ချုပ်သူက ပြဿနာကို ဖြေရှင်းနိုင်ရန် ချွတ်ယွင်းချက်အစီရင်ခံစာကို တောင်းဆိုပါသည်"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"လက်ခံပါ"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ငြင်းပယ်ပါ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"ချွတ်ယွင်းချက် စာရင်းကို ယူနေပါသည်..."</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"ဖျက်သိမ်းရန် တို့ပါ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"ကီးဘုတ် ပြောင်းလဲရန်"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"ကီးဘုတ်များကို ရွေးရန်"</string>
     <string name="show_ime" msgid="9157568568695230830">"ရိုက်သွင်းမှု နည်းလမ်းကို ပြရန်"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index cc861cd..9efa863 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Feilrapport"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Utfør feilrapport"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Informasjon om tilstanden til enheten din samles inn og sendes som en e-post. Det tar litt tid fra du starter feilrapporten til e-posten er klar, så vær tålmodig."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Stillemodus"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Lyden er av"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Lyden er på"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Trykk for å se flere alternativer."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-feilsøking tilkoblet"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Trykk for å slå av USB-feilsøking."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Vil du dele feilrapporten med administratoren?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IT-administratoren din har bedt om en feilrapport for å hjelpe med feilsøkingen"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"GODTA"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"AVSLÅ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Kjører feilrapport …"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Trykk for å avbryte"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Endre tastatur"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Velg tastatur"</string>
     <string name="show_ime" msgid="9157568568695230830">"Vis inndatametode"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Diverse"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Du angir viktigheten for disse varslene."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Dette er viktig på grunn av folkene som er involvert."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" prøver å legge til en ny bruker, men den har for øyeblikket ikke de nødvendige tillatelsene."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" prøver å legge til en ny bruker, men brukergrensen er nådd."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" prøver å legge til en ny bruker, men kontoen "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" finnes allerede på denne enheten. Vil du fortsette likevel?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" prøver å legge til en ny bruker på kontoen "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Vil du fortsette?"</string>
 </resources>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index 1e72bbe..f7b96d9 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"बग रिपोर्ट"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"बग रिपोर्ट लिनुहोस्"</string>
     <string name="bugreport_message" msgid="398447048750350456">"एउटा इमेल सन्देशको रूपमा पठाउनलाई यसले तपाईँको हालैको उपकरणको अवस्थाको बारेमा सूचना जम्मा गर्ने छ। बग रिपोर्ट सुरु गरेदेखि पठाउन तयार नभएसम्म यसले केही समय लिन्छ; कृपया धैर्य गर्नुहोस्।"</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"मौन मोड"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"आवाज बन्द छ"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ध्वनि खुल्ला छ"</string>
@@ -1038,18 +1047,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"थप विकल्पहरूका लागि छुनुहोस्।"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डिबग गर्ने जडित छ"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB डिबग गर्ने असक्षम पार्न छुनुहोस्।"</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"व्यवस्थापकसँग बग रिपोर्ट साझेदारी गर्ने हो?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"तपाईंको IT व्यवस्थापकले समस्या निवारणमा मद्दत गर्न बग रिपोर्ट अनुरोध गर्नुभयो"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"स्वीकार गर्नुहोस्"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"अस्वीकार गर्नुहोस्"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"बग रिपोर्ट लिँदै..."</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"रद्द गर्न छुनुहोस्"</string>
     <string name="select_input_method" msgid="8547250819326693584">"कुञ्जीपाटी परिवर्तन गर्नुहोस्"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"कीबोर्ड छान्नुहोस्"</string>
     <string name="show_ime" msgid="9157568568695230830">"आगत विधि देखाउनुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index b84d6a8..cd70afa 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Foutenrapport"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Foutenrapport genereren"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Hiermee worden gegevens over de huidige status van je apparaat verzameld en als e-mail verzonden. Wanneer u een foutenrapport start, duurt het even voordat het kan worden verzonden. Even geduld alstublieft."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Stille modus"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Geluid is UIT"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Geluid is AAN"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Tik voor meer opties."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-foutopsporing verbonden"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Tik om USB-foutopsporing uit te schakelen."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Bugrapport delen met beheerder?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Je IT-beheerder heeft een bugrapport aangevraagd om het probleem op te lossen"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACCEPTEREN"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"WEIGEREN"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Bugrapport genereren…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Tik om te annuleren"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Toetsenbord wijzigen"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Toetsenborden kiezen"</string>
     <string name="show_ime" msgid="9157568568695230830">"Invoermethode weergeven"</string>
diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml
index 4c3e6d5..7c9f1b4 100644
--- a/core/res/res/values-pa-rIN/strings.xml
+++ b/core/res/res/values-pa-rIN/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"ਬਗ ਰਿਪੋਰਟ"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"ਬਗ ਰਿਪੋਰਟ ਲਓ"</string>
     <string name="bugreport_message" msgid="398447048750350456">"ਇਹ ਇੱਕ ਈ-ਮੇਲ ਸੁਨੇਹਾ ਭੇਜਣ ਲਈ, ਤੁਹਾਡੀ ਵਰਤਮਾਨ ਡਿਵਾਈਸ ਬਾਰੇ ਜਾਣਕਾਰੀ ਇਕੱਤਰ ਕਰੇਗਾ। ਬਗ ਰਿਪੋਰਟ ਸ਼ੁਰੂ ਕਰਨ ਵਿੱਚ ਥੋੜ੍ਹਾ ਸਮਾਂ ਲੱਗੇਗਾ ਜਦੋਂ ਤੱਕ ਇਹ ਭੇਜੇ ਜਾਣ ਲਈ ਤਿਆਰ ਨਾ ਹੋਵੇ, ਕਿਰਪਾ ਕਰਕੇ ਧੀਰਜ ਰੱਖੋ।"</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"ਸਾਈਲੈਂਟ ਮੋਡ"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ਅਵਾਜ਼ ਬੰਦ ਹੈ"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ਅਵਾਜ਼ ਚਾਲੂ ਹੈ"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"ਹੋਰ ਵਿਕਲਪਾਂ ਲਈ ਸਪਰਸ਼ ਕਰੋ।"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ਡੀਬਗਿੰਗ ਕਨੈਕਟ ਕੀਤੀ"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ਡੀਬਗਿੰਗ ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਉਣ ਲਈ ਛੋਹਵੋ।"</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"ਕੀ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਬੱਗ ਰਿਪੋਰਟ ਸਾਂਝੀ ਕਰਨੀ ਹੈ?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"ਸਮੱਸਿਆ ਦੇ ਨਿਪਟਾਰੇ ਵਿੱਚ ਮਦਦ ਲਈ ਤੁਹਾਡੇ IT ਪ੍ਰਸ਼ਾਸਕ ਨੇ ਇੱਕ ਬੱਗ ਰਿਪੋਰਟ ਦੀ ਬੇਨਤੀ ਕੀਤੀ"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ਸਵੀਕਾਰ ਕਰੋ"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"ਬੱਗ ਰਿਪਰੋਟ ਪ੍ਰਾਪਤ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ..."</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"ਰੱਦ ਕਰਨ ਲਈ ਸਪਰਸ਼ ਕਰੋ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"ਕੀਬੋਰਡ ਬਦਲੋ"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"ਕੀਬੋਰਡਸ ਚੁਣੋ"</string>
     <string name="show_ime" msgid="9157568568695230830">"ਇਨਪੁਟ ਵਿਧੀ ਦਿਖਾਓ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index aa4fdcd..1e5bc5f 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -213,6 +213,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Zgłoszenie błędu"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Zgłoś błąd"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Informacje o bieżącym stanie urządzenia zostaną zebrane i wysłane e-mailem. Przygotowanie zgłoszenia błędu do wysłania chwilę potrwa, więc zachowaj cierpliwość."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Tryb cichy"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Dźwięk jest wyłączony"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Dźwięk jest włączony"</string>
@@ -1046,18 +1055,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Kliknij, by zobaczyć więcej opcji."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Podłączono moduł debugowania USB"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Dotknij, aby wyłączyć debugowanie USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Udostępnić raport o błędzie administratorowi?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Administrator poprosił o raport o błędzie, który pomoże w rozwiązaniu problemu"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"AKCEPTUJ"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ODRZUĆ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Zgłaszam błąd…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Kliknij, by anulować"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Zmień klawiaturę"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Wybierz klawiatury"</string>
     <string name="show_ime" msgid="9157568568695230830">"Pokaż metodę wprowadzania"</string>
@@ -1560,12 +1563,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Inne"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Ustawiłeś ważność tych powiadomień."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Ta wiadomość jest ważna ze względu na osoby uczestniczące w wątku."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315">"Aplikacja "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" próbuje dodać nowego użytkownika, ale jest obecnie zabroniona."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266">"Aplikacja "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" próbuje dodać nowego użytkownika, ale osiągnięto już limit użytkowników."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789">"Aplikacja "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" próbuje dodać nowego użytkownika, ale na tym urządzeniu istnieje już konto "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Kontynuować mimo to?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392">"Aplikacja "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" próbuje dodać nowego użytkownika do konta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Kontynuować?"</string>
 </resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 2c4b29b..1d0d9e5 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Relatório de bugs"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Obter relatório de bugs"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Isto coletará informações sobre o estado atual do dispositivo para enviá-las em uma mensagem de e-mail. Após iniciar o relatório de bugs, será necessário aguardar algum tempo até que esteja pronto para ser enviado."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modo silencioso"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Som DESATIVADO"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"O som está ATIVADO"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Toque para ver mais opções."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Toque para desativar a depuração do USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Compartilhar o relatório do bug com o administrador?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Seu administrador de TI solicitou um relatório do bug para ajudar a resolver problemas"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACEITAR"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"RECUSAR"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Gerando relatório do bug..."</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Toque para cancelar"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Alterar teclado"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Escolher teclados"</string>
     <string name="show_ime" msgid="9157568568695230830">"Mostrar método de entrada"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Diversos"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Você definiu a importância dessas notificações."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Isso é importante por causa das pessoas envolvidas."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está tentando adicionar um novo usuário, mas isso não é permitido no momento."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está tentando adicionar um novo usuário, mas o limite de usuários foi atingido."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está tentando adicionar um novo usuário, mas a conta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" já existe neste dispositivo. Continuar mesmo assim?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está tentando adicionar um novo usuário à conta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Continuar?"</string>
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 1131605..453179a 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Relatório de erros"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Criar relatório de erros"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Será recolhida informação sobre o estado atual do seu dispositivo a enviar através de uma mensagem de email. Demorará algum tempo até que o relatório de erro esteja pronto para ser enviado. Aguarde um pouco."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modo silencioso"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Som desativado"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"O som está ativado"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Toque para ver mais opções."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB ligada"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Toque para desat. a depuração USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Pretende partilhar o relatório de erros com o administrador?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"O seu administrador de TI solicitou um relatório de erros para ajudar na resolução de problemas"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACEITAR"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"RECUSAR"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"A criar relatório de erros…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Toque para cancelar"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Alterar teclado"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Escolher teclados"</string>
     <string name="show_ime" msgid="9157568568695230830">"Mostrar método de entrada"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Diversos"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Definiu a importância destas notificações."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"É importante devido às pessoas envolvidas."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está a tentar adicionar um novo utilizador, mas está atualmente proibido."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está a tentar adicionar um novo utilizador, mas foi atingido o limite de utilizadores."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está a tentar adicionar um novo utilizador, mas a conta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" já existe neste dispositivo. Pretende continuar mesmo assim?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está a tentar adicionar um novo utilizador à conta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Pretende continuar?"</string>
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 2c4b29b..1d0d9e5 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Relatório de bugs"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Obter relatório de bugs"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Isto coletará informações sobre o estado atual do dispositivo para enviá-las em uma mensagem de e-mail. Após iniciar o relatório de bugs, será necessário aguardar algum tempo até que esteja pronto para ser enviado."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modo silencioso"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Som DESATIVADO"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"O som está ATIVADO"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Toque para ver mais opções."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Toque para desativar a depuração do USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Compartilhar o relatório do bug com o administrador?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Seu administrador de TI solicitou um relatório do bug para ajudar a resolver problemas"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACEITAR"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"RECUSAR"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Gerando relatório do bug..."</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Toque para cancelar"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Alterar teclado"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Escolher teclados"</string>
     <string name="show_ime" msgid="9157568568695230830">"Mostrar método de entrada"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Diversos"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Você definiu a importância dessas notificações."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Isso é importante por causa das pessoas envolvidas."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está tentando adicionar um novo usuário, mas isso não é permitido no momento."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está tentando adicionar um novo usuário, mas o limite de usuários foi atingido."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está tentando adicionar um novo usuário, mas a conta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" já existe neste dispositivo. Continuar mesmo assim?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" está tentando adicionar um novo usuário à conta "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Continuar?"</string>
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 6dc30af..3602d91 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -212,6 +212,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Raport despre erori"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Executați un raport despre erori"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Acest raport va colecta informații despre starea actuală a dispozitivului, pentru a le trimite într-un e-mail. Aveți răbdare după pornirea raportului despre erori până când va fi gata de trimis."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mod Silențios"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Sunetul este DEZACTIVAT"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Sunetul este ACTIVAT"</string>
@@ -1039,18 +1048,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Atingeți pentru mai multe opțiuni."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depanarea USB este conectată"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Atingeți pentru a dezactiva depanarea USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Trimiteți raportul de eroare administratorului?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Administratorul IT a solicitat un raport de eroare pentru a remedia problemele"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACCEPTAȚI"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"REFUZAȚI"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Se creează un raport de eroare…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Atingeți pentru a anula"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Schimbați tastatura"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Alegeți tastaturi"</string>
     <string name="show_ime" msgid="9157568568695230830">"Afișați metoda de introducere a textului"</string>
@@ -1542,12 +1545,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Diverse"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Dvs. setați importanța acestor notificări."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Notificarea este importantă având în vedere persoanele implicate."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" încearcă să adauge un nou utilizator, dar momentan nu îi este permis."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" încearcă să adauge un nou utilizator, dar a fost atinsă limita de utilizatori."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" încearcă să adauge un nou utilizator, dar contul "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" există deja pe acest dispozitiv. Continuați oricum?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" încearcă să adauge un nou utilizator pentru contul "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Continuați?"</string>
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index c6e7b71..2d69607 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -213,6 +213,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Отчет об ошибке"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Отчет об ошибке"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Информация о текущем состоянии вашего устройства будет собрана и отправлена по электронной почте. Подготовка отчета займет некоторое время."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Режим без звука"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Выключить"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Включить"</string>
@@ -1046,18 +1055,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Нажмите, чтобы настроить."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отладка по USB разрешена"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Нажмите, чтобы отключить отладку по USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Отправить администратору информацию об ошибке?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Ваш администратор запросил информацию об ошибке. Эти данные помогут устранить неполадку."</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ПРИНЯТЬ"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ОТКЛОНИТЬ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Подождите…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Нажмите, чтобы отменить"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Выбор раскладки"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Выбрать раскладку"</string>
     <string name="show_ime" msgid="9157568568695230830">"Показать способ ввода"</string>
@@ -1560,12 +1563,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Другое"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Вы определяете важность этих уведомлений."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Важное (люди)"</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315">"Приложение "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" хочет добавить пользователя, однако в настоящее время это действие запрещено."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266">"Приложение "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" хочет добавить пользователя, однако лимит уже достигнут."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789">"Приложение "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" хочет добавить пользователя, однако аккаунт "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" уже есть на этом устройстве. Продолжить?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392">"Приложение "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" хочет добавить пользователя для аккаунта "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Продолжить?"</string>
 </resources>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 5c381e3..fb36adc 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"දෝෂ වර්තාව"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"දෝෂ වාර්තාවක් ගන්න"</string>
     <string name="bugreport_message" msgid="398447048750350456">"ඊ-තැපැල් පණිවිඩයක් ලෙස යැවීමට මෙය ඔබගේ වත්මන් උපාංග තත්වය ගැන තොරතුරු එකතු කරනු ඇත. දෝෂ වාර්තාව ආරම්භ කර එය යැවීමට සූදානම් කරන තෙක් එයට කිසියම් කාලයක් ගතවනු ඇත; කරුණාකර ඉවසන්න."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"නිහඬ ආකාරය"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ශබ්දය අක්‍රියයි"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"හඬ සක්‍රියයි"</string>
@@ -1034,18 +1043,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"වඩා වැඩි විකල්ප සඳහා ස්පර්ශ කරන්න."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB නිදොස්කරණය සම්බන්ධිතයි"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB නිදොස්කරණය අබල කිරීමට ස්පර්ශ කරන්න."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"පරිපාලක සමඟ දෝෂ වාර්තාවක් බෙදා ගන්නද?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"දෝෂාවේක්ෂණය සඳහා උදවු කිරීමට ඔබේ IT පරිපාලක දෝෂ වාර්තාවක් ඉල්ලා ඇත"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"පිළිගන්න"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ප්‍රතික්ෂේප කරන්න"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"දෝෂ වාර්තාවක් ගනිමින්…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"අවලංගු කිරීමට ස්පර්ශ කරන්න"</string>
     <string name="select_input_method" msgid="8547250819326693584">"යතුරු පුවරු වෙනස් කිරීම"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"යතුරු පුවරු තෝරන්න"</string>
     <string name="show_ime" msgid="9157568568695230830">"ආදාන ක්‍රමය පෙන්වන්න"</string>
@@ -1526,12 +1529,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"විවිධාකාර"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"ඔබ මෙම දැනුම්දීම්වල වැදගත්කම සකසා ඇත."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"සම්බන්ධ වූ පුද්ගලයන් නිසා මෙය වැදගත් වේ."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" නව පරිශීලකයෙකු එක් කිරීමට උත්සාහ කරමින් සිටින නමුත්, දැනට තහනම්ය."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" නව පරිශීලකයෙකු එක් කිරීමට උත්සාහ කරමින් සිටින නමුත්, පරිශීලක සීමාවට ළඟා වී ඇත."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" නව පරිශීලකයෙකු එක් කිරීමට උත්සාහ කරමින් සිටී, නමුත් "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ගිණුම මෙම උපාංගය මත දැනටමත් පවතී. කෙසේ වෙතත් ඉදිරියට යන්නද?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" නව පරිශීලකයෙකු "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ගිණුම සඳහා එක් කිරීමට උත්සාහ කරමින් සිටී. ඉදිරියට යන්නද?"</string>
 </resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index ef738cb..d81e4e73 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -213,6 +213,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Hlásenie o chybách"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Vytvoriť hlásenie chyby"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Týmto zhromaždíte informácie o aktuálnom stave zariadenia. Informácie je potom možné odoslať e-mailom, chvíľu však potrvá, kým bude hlásenie chyby pripravené na odoslanie. Prosíme vás preto o trpezlivosť."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Tichý režim"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Zvuk je VYPNUTÝ."</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Zvuk je zapnutý"</string>
@@ -1046,18 +1055,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Ďalšie možnosti zobrazíte klepnutím."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Ladenie cez USB pripojené"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Klepnutím zakážete ladenie cez USB"</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Zdieľať hlásenie chyby so správcom?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Správca IT si vyžiadal hlásenie chyby, aby mohol problém vyriešiť"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"PRIJAŤ"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ODMIETNUŤ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Vytvára sa hlásenie chyby…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Dotykom zrušíte"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Zmeniť klávesnicu"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Vybrať klávesnicu"</string>
     <string name="show_ime" msgid="9157568568695230830">"Zobraziť metódu vstupu"</string>
@@ -1560,12 +1563,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Rôzne"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Nastavili ste dôležitosť týchto upozornení."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Táto správa je dôležitá vzhľadom na osoby, ktorých sa to týka."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315">"Aplikácia "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" sa pokúša pridať nového používateľa, avšak momentálne je zakázaná."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266">"Aplikácia "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" sa pokúša pridať nového používateľa, bol však prekročený limit počtu používateľov."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789">"Aplikácia "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" sa pokúša pridať nového používateľa, účet "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" však na tomto zariadení už existuje. Chcete napriek tomu pokračovať?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392">"Aplikácia "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" sa pokúša pridať nového používateľa pre účet "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Chcete pokračovať?"</string>
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 224ecb1..c86227e 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -213,6 +213,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Poročilo o napakah"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Ustvari poročilo o napakah"</string>
     <string name="bugreport_message" msgid="398447048750350456">"S tem bodo zbrani podatki o trenutnem stanju naprave, ki bodo poslani v e-poštnem sporočilu. Izvedba poročila o napakah in priprava trajata nekaj časa, zato bodite potrpežljivi."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Tihi način"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Zvok je IZKLOPLJEN"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Zvok je VKLOPLJEN"</string>
@@ -1046,18 +1055,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Za več možnosti se dotaknite."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Iskanje in odpravljanje napak USB je povezano"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Dotaknite se, če želite onemogočiti iskanje in odpravljanje napak prek vrat USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Želite skrbniku poslati poročilo o napakah?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Skrbnik IT je zahteval poročilo o napakah za pomoč pri odpravljanju napak"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"SPREJMEM"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"NE SPREJMEM"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Zajemanje poročila o napakah …"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Če želite prekiniti, se dotaknite"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Sprememba tipkovnice"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Izbira tipkovnic"</string>
     <string name="show_ime" msgid="9157568568695230830">"Pokaži način vnosa"</string>
@@ -1560,12 +1563,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Razno"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Vi določite raven pomembnosti teh obvestil."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Pomembno zaradi udeleženih ljudi."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315">"Aplikacija "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" poskuša dodati novega uporabnika, vendar trenutno nima dovoljenja."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266">"Aplikacija "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" poskuša dodati novega uporabnika, vendar je dosežena omejitev števila uporabnikov."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789">"Aplikacija "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" poskuša dodati novega uporabnika, vendar račun "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" v napravi že obstaja. Ali želite kljub temu nadaljevati?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392">"Aplikacija "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" poskuša dodati novega uporabnika za račun "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Ali želite nadaljevati?"</string>
 </resources>
diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml
index 70ce5a7..c33dc5b 100644
--- a/core/res/res/values-sq-rAL/strings.xml
+++ b/core/res/res/values-sq-rAL/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Raporti i defekteve në kod"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Merr raportin e defekteve në kod"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Ky funksion mundëson mbledhjen e informacioneve mbi gjendjen aktuale të pajisjes për ta dërguar si mesazh mail-i. Do të duhet pak kohë nga nisja e raportit të defekteve në kod. Faleminderit për durimin."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modaliteti \"në heshtje\""</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Zëri është çaktivizuar"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Zëri është i aktivizuar"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Prek për më shumë opsione."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Korrigjuesi i USB-së i lidhur"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Prek për të çaktivizuar korrigjimin e gabimeve të USB-së."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Ndaje raportin e defekteve në kod me administratorin?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Administratori i teknologjisë së informacionit kërkoi një raport të defekteve në kod për të ndihmuar me zgjidhjen e problemeve"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"PRANO"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"REFUZO"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Po merret raporti i defekteve në kod…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Prek për ta anuluar"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Ndërro tastierë"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Zgjidh tastierat"</string>
     <string name="show_ime" msgid="9157568568695230830">"Shfaq metodën e hyrjes"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Të ndryshme"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Ke caktuar rëndësinë e këtyre njoftimeve."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Është i rëndësishëm për shkak të personave të përfshirë."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" po përpiqet të shtojë një përdorues të ri, por aktualisht nuk i lejohet."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" po përpiqet të shtojë një përdorues të ri, por është arritur limiti i përdoruesve."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" po provon të shtojë një përdorues të ri, por llogaria "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ekziston tashmë në këtë pajisje. Dëshiron të vazhdosh gjithsesi?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" po provon të shtojë një përdorues të ri për llogarinë "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Dëshiron të vazhdosh?"</string>
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 607c7db..04a170c 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -212,6 +212,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Извештај о грешци"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Направи извештај о грешци"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Овим ће се прикупити информације о тренутном стању уређаја како би биле послате у поруци е-поште. Од започињања извештаја о грешци до тренутка за његово слање проћи ће неко време; будите стрпљиви."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Нечујни режим"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Звук је ИСКЉУЧЕН"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Звук је УКЉУЧЕН"</string>
@@ -1039,18 +1048,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Додирните за још опција."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отклањање грешака са USB-а је успостављено"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Додирните да бисте онемогућили отклањање грешака са USB-а."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Желите ли да делите извештај о грешци са администратором?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"ИТ администратор је затражио извештај о грешци ради лакшег решавања проблема"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ПРИХВАТИ"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ОДБИЈ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Извештај о грешци се генерише…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Додирните да бисте отказали"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Промените тастатуру"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Изаберите тастатуре"</string>
     <string name="show_ime" msgid="9157568568695230830">"Приказивање метода уноса"</string>
@@ -1542,12 +1545,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Разно"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Ви подешавате важност ових обавештења."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Ово је важно због људи који учествују."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" покушава да дода новог корисника, али то је тренутно забрањено."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" покушава да дода новог корисника, али је ограничење за број корисника достигнуто."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" покушава да дода новог корисника, али налог "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" већ постоји на овом уређају. Желите ли ипак да наставите?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" покушава да дода новог корисника за налог "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Желите ли да наставите?"</string>
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index b1bef2c..346b1234 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Felrapport"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Skapa felrapport"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Nu hämtas information om aktuell status för enheten, som sedan skickas i ett e-postmeddelade. Det tar en liten stund innan felrapporten är färdig och kan skickas, så vi ber dig ha tålamod."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Tyst läge"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Ljudet är AV"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Ljudet är PÅ"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Visa fler alternativ genom att trycka."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-felsökning ansluten"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Tryck om du vill inaktivera USB-felsökning."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Vill du dela en felrapport med administratören?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IT-administratören har bett om en felrapport som hjälp vid felsökningen."</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"GODKÄNN"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"AVVISA"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Felrapporten överförs …"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Tryck här om du vill avbryta"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Byt tangentbord"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Välj tangentbord"</string>
     <string name="show_ime" msgid="9157568568695230830">"Visa inmatningsmetod"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Diverse"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Du anger hur viktiga aviseringarna är."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Detta är viktigt på grund av personerna som deltar."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" försöker lägga till en ny användare, men får inte göra det för närvarande."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" försöker lägga till en ny användare, men gränsen för antal användare har uppnåtts."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" försöker lägga till en ny användare, men kontot "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" finns redan på den här enheten. Vill du fortsätta ändå?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" försöker lägga till en ny användare för kontot "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Vill du fortsätta?"</string>
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 97d4367..714827c 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -213,6 +213,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Ripoti ya hitilafu"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Chukua ripoti ya hitilafu"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Hii itakusanya maelezo kuhusu hali ya kifaa chako kwa sasa, na itume kama barua pepe. Itachukua muda mfupi tangu ripoti ya hitilafu ianze kuzalishwa hadi iwe tayari kutumwa; vumilia."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mtindo wa kimya"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Sauti Imezimwa"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Sauti imewashwa"</string>
@@ -1034,18 +1043,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Gusa kwa chaguo zaidi."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Utatuaji wa USB umeunganishwa"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Gusa ili uzime utatuaji wa USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Ungependa kushiriki ripoti ya hitilafu na msimamizi?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Msimamizi wako wa IT ameomba ripoti ya hitilafu ili kusaidia katika utatuzi"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"KUBALI"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"KATAA"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Inatayarisha ripoti ya hitilafu…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Gusa ili ufute"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Badilisha kibodi"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Chagua kibodi"</string>
     <string name="show_ime" msgid="9157568568695230830">"Onyesha mbinu ya kuingiza"</string>
@@ -1526,12 +1529,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Anuwai"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Uliweka umuhimu wa arifa hizi."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Hii ni muhimu kwa sababu ya watu waliohusika."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" inajaribu kuongeza mtumiaji mpya, lakini hatua hii hairuhusiwi kwa sasa."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" inajaribu kuongeza mtumiaji mpya, lakini idadi ya juu ya watumiaji imefikiwa."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" inajaribu kuongeza mtumiaji mpya, lakini akaunti ya "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" tayari ipo kwenye kifaa hiki. Ungependa kundelea?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" inajaribu kuongeza mtumiaji mpya kwenye akaunti ya "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Ungependa kuendelea?"</string>
 </resources>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index cd0c054..38c2e26 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"பிழை அறிக்கை"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"பிழை அறிக்கையை எடு"</string>
     <string name="bugreport_message" msgid="398447048750350456">"உங்கள் நடப்புச் சாதன நிலையை மின்னஞ்சல் செய்தியாக அனுப்ப, அது குறித்த தகவலை இது சேகரிக்கும். பிழை அறிக்கையைத் தொடங்குவதில் இருந்து, அது அனுப்புவதற்குத் தயாராகும் வரை, இதற்குச் சிறிது நேரம் ஆகும்; பொறுமையாகக் காத்திருக்கவும்."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"நிசப்த பயன்முறை"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ஒலி முடக்கத்தில் உள்ளது"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ஒலி இயக்கத்தில் உள்ளது"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"கூடுதல் விருப்பங்களுக்காகத் தொடவும்."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB பிழைதிருத்தம் இணைக்கப்பட்டது"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB பிழைத்திருத்தத்தை முடக்க, தொடவும்."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"பிழை அறிக்கையை நிர்வாகியுடன் பகிரவா?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"பிழைகாண்பதற்கு உதவ, உங்கள் ஐடி நிர்வாகி பிழை அறிக்கையைக் கோரியுள்ளார்"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"சரி"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"நிராகரி"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"பிழை அறிக்கையை எடுக்கிறது…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"ரத்துசெய்ய, தொடவும்"</string>
     <string name="select_input_method" msgid="8547250819326693584">"விசைப்பலகையை மாற்று"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"விசைப்பலகைகளைத் தேர்வுசெய்க"</string>
     <string name="show_ime" msgid="9157568568695230830">"உள்ளீட்டு முறையைக் காட்டு"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"இதர அமைப்பு"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"இந்த அறிவிப்புகளின் முக்கியத்துவத்தை அமைத்துள்ளீர்கள்."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"ஈடுபட்டுள்ளவர்களின் காரணமாக, இது முக்கியமானது."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" பயன்பாடு புதிய பயனரைச் சேர்க்க முயல்கிறது, ஆனால் பயனரைச் சேர்ப்பது தற்போது தடுக்கப்பட்டுள்ளது."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" பயன்பாடு புதிய பயனரைச் சேர்க்க முயல்கிறது, ஆனால் பயனருக்கான வரம்பு முடிந்துவிட்டது."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" பயன்பாடு புதிய பயனரைச் சேர்க்க முயல்கிறது. ஆனால் "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" கணக்கு ஏற்கனவே இந்தச் சாதனத்தில் உள்ளது. தொடரவா?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" பயன்பாடு "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" கணக்கிற்குப் புதிய பயனரைச் சேர்க்க முயல்கிறது. தொடரவா?"</string>
 </resources>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 1946ed0..14cc2c1 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"బగ్ నివేదిక"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"బగ్ నివేదికను సిద్ధం చేయి"</string>
     <string name="bugreport_message" msgid="398447048750350456">"ఇది ఇ-మెయిల్ సందేశం రూపంలో పంపడానికి మీ ప్రస్తుత పరికర స్థితి గురించి సమాచారాన్ని సేకరిస్తుంది. బగ్ నివేదికను ప్రారంభించడం మొదలుకొని పంపడానికి సిద్ధం చేసే వరకు ఇందుకు కొంత సమయం పడుతుంది; దయచేసి ఓపిక పట్టండి."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"నిశ్శబ్ద మోడ్"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ధ్వని ఆఫ్‌లో ఉంది"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"ధ్వని ఆన్‌లో ఉంది"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"మరిన్ని ఎంపికల కోసం తాకండి."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB డీబగ్గింగ్ కనెక్ట్ చేయబడింది"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB డీబగ్గింగ్‌ను నిలిపివేయడానికి తాకండి."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"బగ్ నివేదికను నిర్వాహకులకు భాగస్వామ్యం చేయాలా?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"మీ ఐటి నిర్వాహకులు సమస్య పరిష్కారాన్ని కనుగొనడంలో సహాయం కోసం బగ్ నివేదికను అభ్యర్థించారు"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ఆమోదిస్తున్నాను"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"తిరస్కరిస్తున్నాను"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"బగ్ నివేదికను తీస్తోంది…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"రద్దు చేయడానికి తాకండి"</string>
     <string name="select_input_method" msgid="8547250819326693584">"కీబోర్డ్‌ను మార్చు"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"కీబోర్డ్‌లను ఎంచుకోండి"</string>
     <string name="show_ime" msgid="9157568568695230830">"ఇన్‌పుట్ పద్ధతిని చూపు"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"ఇతరాలు"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"మీరు ఈ నోటిఫికేషన్‌ల ప్రాముఖ్యతను సెట్ చేసారు."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"ఇందులో పేర్కొనబడిన వ్యక్తులను బట్టి ఇది చాలా ముఖ్యమైనది."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" కొత్త వినియోగదారుని జోడించడానికి ప్రయత్నిస్తోంది, కానీ ప్రస్తుతం ఇది నిషిద్ధం."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" కొత్త వినియోగదారుని జోడించడానికి ప్రయత్నిస్తోంది, కానీ వినియోగదారు పరిమితి చేరుకుంది."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" కొత్త వినియోగదారుని జోడించడానికి ప్రయత్నిస్తోంది, కానీ ఖాతా "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ఇప్పటికే ఈ పరికరంలో ఉంది. ఏదేమైనా కొనసాగించాలా?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ఖాతా "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" కోసం కొత్త వినియోగదారుని జోడించడానికి ప్రయత్నిస్తోంది. కొనసాగించాలా?"</string>
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 3e4d948..59f6ffa 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"รายงานข้อบกพร่อง"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"ใช้รายงานข้อบกพร่อง"</string>
     <string name="bugreport_message" msgid="398447048750350456">"การดำเนินการนี้จะรวบรวมข้อมูลเกี่ยวกับสถานะปัจจุบันของอุปกรณ์ของคุณ โดยจะส่งไปในรูปแบบข้อความอีเมล อาจใช้เวลาสักครู่ตั้งแต่เริ่มการสร้างรายงานข้อบกพร่องจนกระทั่งเสร็จสมบูรณ์ โปรดอดทนรอ"</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"โหมดปิดเสียง"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ปิดเสียงไว้"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"เปิดเสียงแล้ว"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"แตะเพื่อดูตัวเลือกเพิ่มเติม"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"เชื่อมต่อการแก้ไขข้อบกพร่อง USB แล้ว"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"แตะเพื่อปิดใช้งานการแก้ไขข้อบกพร่อง USB"</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"ต้องการแชร์รายงานข้อบกพร่องกับผู้ดูแลระบบไหม"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"ผู้ดูแลระบบไอทีของคุณขอรายงานข้อบกพร่องเพื่อช่วยในการแก้ไขปัญหา"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ยอมรับ"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ปฏิเสธ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"กำลังสร้างรายงานข้อบกพร่อง…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"แตะเพื่อยกเลิก"</string>
     <string name="select_input_method" msgid="8547250819326693584">"เปลี่ยนแป้นพิมพ์"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"เลือกแป้นพิมพ์"</string>
     <string name="show_ime" msgid="9157568568695230830">"แสดงวิธีการป้อนข้อมูล"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"เบ็ดเตล็ด"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"คุณตั้งค่าความสำคัญของการแจ้งเตือนเหล่านี้"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"ข้อความนี้สำคัญเนื่องจากบุคคลที่เกี่ยวข้อง"</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" กำลังพยายามเพิ่มผู้ใช้ใหม่ แต่ระบบไม่อนุญาตในขณะนี้"</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" กำลังพยายามเพิ่มผู้ใช้ใหม่ แต่ถึงขีดจำกัดของผู้ใช้แล้ว"</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" กำลังพยายามเพิ่มผู้ใช้ใหม่ แต่มีบัญชี "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" อยู่แล้วบนอุปกรณ์เครื่องนี้ ดำเนินการต่อไหม"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" กำลังพยายามเพิ่มผู้ใช้ใหม่สำหรับบัญชี "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" ดำเนินการต่อไหม"</string>
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 8b79f4b..c6e643b 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Ulat sa bug"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Kunin ang ulat sa bug"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Mangongolekta ito ng impormasyon tungkol sa kasalukuyang katayuan ng iyong device, na ipapadala bilang mensaheng e-mail. Gugugol ito ng kaunting oras mula sa pagsisimula ng ulat sa bug hanggang sa handa na itong maipadala; mangyaring magpasensya."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Silent mode"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Naka-OFF ang tunog"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Naka-ON ang sound"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Pindutin para sa higit pang mga opsyon."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Konektado ang debugging ng USB"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Pindutin upang i-disable ang pagde-debug ng USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Ibahagi ang ulat ng bug sa admin?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Humiling ang iyong admin ng IT ng ulat ng bug upang makatulong sa pag-troubleshoot"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"TANGGAPIN"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"TANGGIHAN"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Kinukuha ang ulat ng bug…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Pindutin upang kanselahin"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Baguhin ang keyboard"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Pumili ng mga keyboard"</string>
     <string name="show_ime" msgid="9157568568695230830">"Ipakita ang pamamaraan ng pag-input"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Iba Pa"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Ikaw ang magtatakda ng kahalagahan ng mga notification na ito."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Mahalaga ito dahil sa mga taong kasangkot."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315">"Sinusubukan ng "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" na magdagdag ng bagong user, ngunit kasalukuyan itong ipinagbabawal."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266">"Sinusubukan ng "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" na magdagdag ng bagong user, ngunit naabot na ang limitasyon sa user."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789">"Sinusubukan ng "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" na magdagdag ng bagong user, ngunit nasa device na ito na ang account na "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Magpatuloy pa rin?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392">"Sinusubukan ng "<b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" na magdagdag ng bagong user para sa account na "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>". Magpatuloy?"</string>
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index d1a7bf54..3603952 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Hata raporu"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Hata raporu al"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Bu rapor, e-posta iletisi olarak göndermek üzere cihazınızın şu anki durumuyla ilgili bilgi toplar. Hata raporu başlatıldıktan sonra hazır olması biraz zaman alabilir, lütfen sabırlı olun."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Sessiz mod"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Ses KAPALI"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Ses AÇIK"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Daha fazla seçenek için dokunun."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hata ayıklaması bağlandı"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB hata ayıklama özelliğini devre dışı bırakmak için dokunun."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Hata raporu yöneticiyle paylaşılsın mı?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"BT yöneticiniz, sorun gidermeye yardımcı olması için bir hata raporu istedi"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"KABUL ET"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"REDDET"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Hata raporu alınıyor…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"İptal etmek için dokunun"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Klavyeyi değiştir"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Klavyeyi seç"</string>
     <string name="show_ime" msgid="9157568568695230830">"Giriş yöntemini göster"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Çeşitli"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Bu bildirimlerin önem derecesini ayarladınız."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Bu, dahil olan kişiler nedeniyle önemlidir."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>", yeni bir kullanıcı eklemeye çalışıyor, ancak şu anda bunu yapmak için izni yok."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>", yeni bir kullanıcı eklemeye çalışıyor, ancak kullanıcı sınırına ulaşıldı."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>", yeni bir kullanıcı eklemeye çalışıyor, ancak "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" hesabı bu cihazda zaten var. Yine de devam edilsin mi?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>", "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" hesabı için yeni bir kullanıcı eklemeye çalışıyor. Devam edilsin mi?"</string>
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index df4e80b..fdc6323 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -213,6 +213,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Звіт про помилки"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Звіт про помилку"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Інформація про поточний стан вашого пристрою буде зібрана й надіслана електронною поштою. Підготовка звіту триватиме певний час."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Беззвуч. режим"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Звук ВИМК."</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Звук УВІМК."</string>
@@ -1046,18 +1055,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Торкніться, щоб побачити більше опцій."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Налагодження USB завершено"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Торкніться, щоб вимкнути налагодження USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Надіслати адміністратору повідомлення про помилку?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Ваш ІТ-адміністратор просить надіслати повідомлення про помилку, щоб вирішити проблему"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ПРИЙНЯТИ"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ВІДХИЛИТИ"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Створюється повідомлення про помилку…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Торкніться, щоб скасувати"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Змінити клавіатуру"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Вибрати клавіатури"</string>
     <string name="show_ime" msgid="9157568568695230830">"Показати метод введення"</string>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index fb83828..14167ac 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"بگ کی اطلاع"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"بگ کی اطلاع لیں"</string>
     <string name="bugreport_message" msgid="398447048750350456">"ایک ای میل پیغام کے بطور بھیجنے کیلئے، یہ آپ کے موجودہ آلہ کی حالت کے بارے میں معلومات جمع کرے گا۔ بگ کی اطلاع شروع کرنے سے لے کر بھیجنے کیلئے تیار ہونے تک اس میں تھوڑا وقت لگے گا؛ براہ کرم تحمل سے کام لیں۔"</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"خاموش وضع"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"آواز آف ہے"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"آواز آن ہے"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"مزید اختیارات کیلئے ٹچ کریں۔"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏USB ڈیبگ کرنا مربوط ہو گیا"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"‏USB ڈیبگنگ کو غیر فعال کرنے کیلئے ٹچ کریں۔"</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"منتظم کے ساتھ بگ رپورٹ کا اشتراک کریں؟"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"‏آپ کے IT منتظم نے ٹربل شوٹ میں مدد کیلئے ایک بگ رپورٹ کی درخواست کی"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"قبول کریں"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"مسترد کریں"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"بگ رپورٹ لی جا رہی ہے…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"منسوخ کرنے کیلئے ٹچ کریں"</string>
     <string name="select_input_method" msgid="8547250819326693584">"کی بورڈ تبدیل کریں"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"کی بورڈز منتخب کریں"</string>
     <string name="show_ime" msgid="9157568568695230830">"ان پٹ طریقہ دکھائیں"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"متفرقات"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"ان اطلاعات کی اہمیت آپ مقرر کرتے ہیں۔"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"اس میں موجود لوگوں کی وجہ سے یہ اہم ہے۔"</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ایک نیا صارف شامل کرنے کی کوشش کر رہی ہے مگر فی الحال ممنوع ہے۔"</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ایک نیا صارف شامل کرنے کی کوشش کر رہی ہے، لیکن صارف کی حد پوری ہوگئی ہے۔"</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ایک نیا صارف شامل کرنے کی کوشش کر رہی ہے لیکن اکاؤنٹ "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" پہلے سے اس آلہ پر موجود ہے۔ بہر صورت آگے بڑھیں؟"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" اکاؤنٹ "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" کیلئے ایک نیا صارف شامل کرنے کی کوشش کر رہی ہے۔ آگے بڑھیں؟"</string>
 </resources>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index 0e71bb4..e904573 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Nosozlik haqida ma’lumot berish"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Xatoliklar hisoboti"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Qurilmangiz holati haqidagi ma’lumotlar to‘planib, e-pochta orqali yuboriladi. Hisobotni tayyorlash biroz vaqt olishi mumkin."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Ovozsiz rejim"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Tovush o‘chirilgan"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"YONIQ"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Sozlash uchun bosing."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB orqali nosozliklarni tuzatish"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"O‘chirib qo‘yish uchun bosing."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Administrator bilan xatoliklar hisoboti ulashilsinmi?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Administratoringiz nosozliklarni tuzatish uchun xatoliklar hisobotini so‘ramoqda"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"QABUL QILISH"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"RAD ETISH"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Xatoliklar hisoboti olinmoqda…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Bekor qilish uchun bosing"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Klaviaturani o‘zgartirish"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Klaviaturani tanlash"</string>
     <string name="show_ime" msgid="9157568568695230830">"Kiritish usulini ko‘rish"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"Boshqa belgilar"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"Siz ushbu bildirishnomalarning muhimligini belgilagansiz."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"Bu odamlar siz uchun muhim."</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ilovasi yangi foydalanuvchi qo‘shishga urinmoqda, lekin hozirda taqiqlangan."</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ilovasi yangi foydalanuvchi qo‘shishga urinmqoda, lekin ortiq foydalanuvchi qo‘shib bo‘lmaydi."</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ilovasi yangi foydalanuvchi qo‘shishga urinmoqda, lekin "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" hisobi allaqachon qurilmada mavjud. Baribir davom etilsinmi?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" ilovasi "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" hisobi uchun yangi foydalanuvchi qo‘shishga urinmoqda. Davom etilsinmi?"</string>
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index e9d47d2..c979b3c4 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Báo cáo lỗi"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Nhận báo cáo lỗi"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Báo cáo này sẽ thu thập thông tin về tình trạng thiết bị hiện tại của bạn, để gửi dưới dạng thông báo qua email. Sẽ mất một chút thời gian kể từ khi bắt đầu báo cáo lỗi cho tới khi báo cáo sẵn sàng để gửi; xin vui lòng kiên nhẫn."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Chế độ im lặng"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Âm thanh TẮT"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Âm thanh BẬT"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Chạm để có các tùy chọn khác."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Gỡ lỗi USB đã được kết nối"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Chạm để vô hiệu hóa gỡ lỗi USB."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Chia sẻ báo cáo lỗi với quản trị viên?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Quản trị viên CNTT của bạn đã yêu cầu báo cáo lỗi để giúp khắc phục sự cố"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"CHẤP NHẬN"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"TỪ CHỐI"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Đang thực hiện báo cáo lỗi…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Chạm để hủy"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Thay đổi bàn phím"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Chọn bàn phím"</string>
     <string name="show_ime" msgid="9157568568695230830">"Hiển thị phương thức nhập"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 723fa8e..fd12d29 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"错误报告"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"提交错误报告"</string>
     <string name="bugreport_message" msgid="398447048750350456">"这会收集有关当前设备状态的信息,并以电子邮件的形式进行发送。从开始生成错误报告到准备好发送需要一点时间,请耐心等待。"</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"静音模式"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"声音已关闭"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"声音已开启"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"触摸以查看更多选项。"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已连接到USB调试"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"触摸可停用USB调试。"</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"要与管理员分享错误报告吗?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"您的 IT 管理员已请求获取错误报告,以便帮助您排查问题"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"接受"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"拒绝"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"正在生成错误报告…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"触摸可取消"</string>
     <string name="select_input_method" msgid="8547250819326693584">"更改键盘"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"选择键盘"</string>
     <string name="show_ime" msgid="9157568568695230830">"显示输入法"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"其他"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"这些通知的重要性由您来设置。"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"这条通知涉及特定的人,因此被归为重要通知。"</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>"正尝试添加新用户,但是系统目前禁止执行这项操作。"</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>"正尝试添加新用户,但已达到用户人数上限。"</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>"正尝试添加新用户,但这个设备上已经存在"<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>"这个帐号。仍要继续吗?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>"正尝试为"<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>"这个帐号添加新用户,要继续吗?"</string>
 </resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 73391da..bd6ec0a 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"錯誤報告"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"取得錯誤報告"</string>
     <string name="bugreport_message" msgid="398447048750350456">"這會收集您目前裝置狀態的相關資訊,並以電郵傳送給您。從開始建立錯誤報告到準備傳送需要一段時間,請耐心等候。"</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"靜音模式"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"關閉音效"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"音效已開啟"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"輕觸以瀏覽更多選項。"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"輕觸即可停用 USB 偵錯。"</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"要與管理員分享錯誤報告嗎?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"您的 IT 管理員要求您提供錯誤報告,以協助解決疑難"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"接受"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"拒絕"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"正在取得錯誤報告…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"輕觸即可取消"</string>
     <string name="select_input_method" msgid="8547250819326693584">"變更鍵盤"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"選擇鍵盤"</string>
     <string name="show_ime" msgid="9157568568695230830">"顯示輸入法"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"其他"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"您可以為這些通知設定重要性。"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"列為重要的原因:涉及的人。"</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" 正在嘗試新增使用者,但系統目前禁止相關操作。"</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" 正在嘗試新增使用者,但使用者人數已達上限。"</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" 正在嘗試新增使用者,但此裝置上已有 "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" 這個帳戶。仍要繼續嗎?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b>"<xliff:g id="APP">%1$s</xliff:g>"</b>" 正在嘗試為 "<b>"<xliff:g id="ACCOUNT">%2$s</xliff:g>"</b>" 這個帳戶新增使用者。要繼續嗎?"</string>
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 8258407..4181697 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"錯誤報告"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"取得錯誤報告"</string>
     <string name="bugreport_message" msgid="398447048750350456">"這會收集您目前裝置狀態的相關資訊,以便透過電子郵件傳送。從錯誤報告開始建立到準備傳送的這段過程可能需要一點時間,敬請耐心等候。"</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"靜音模式"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"音效已關閉"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"音效已開啟"</string>
@@ -245,7 +254,7 @@
     <string name="permgrouplab_phone" msgid="5229115638567440675">"電話"</string>
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"撥打電話及管理通話"</string>
     <string name="permgrouplab_sensors" msgid="416037179223226722">"身體感應器"</string>
-    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"存取生命徵象相關感應器資料"</string>
+    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"存取與您生命徵象相關的感應器資料"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"擷取視窗內容"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"檢查您存取的視窗內容。"</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"啟用輕觸探索功能"</string>
@@ -523,7 +532,7 @@
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"設定裝置全域 Proxy"</string>
     <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"設定政策啟用時要使用的裝置全域 Proxy。只有裝置擁有者可以設定全域 Proxy。"</string>
     <string name="policylab_expirePassword" msgid="5610055012328825874">"設定螢幕鎖定密碼到期日"</string>
-    <string name="policydesc_expirePassword" msgid="5367525762204416046">"調整螢幕鎖定密碼、PIN 碼或解鎖圖形的強制變更頻率。"</string>
+    <string name="policydesc_expirePassword" msgid="5367525762204416046">"調整螢幕鎖定密碼、PIN 碼或解鎖圖案的強制變更頻率。"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"設定儲存裝置加密"</string>
     <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"必須為儲存的應用程式資料進行加密。"</string>
     <string name="policylab_disableCamera" msgid="6395301023152297826">"停用相機"</string>
@@ -658,7 +667,7 @@
     <string name="lockscreen_screen_locked" msgid="7288443074806832904">"螢幕已鎖定。"</string>
     <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"按下 [Menu] 解鎖或撥打緊急電話。"</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"按下 Menu 鍵解鎖。"</string>
-    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"畫出解鎖圖形"</string>
+    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"畫出解鎖圖案"</string>
     <string name="lockscreen_emergency_call" msgid="5298642613417801888">"緊急撥號"</string>
     <string name="lockscreen_return_to_call" msgid="5244259785500040021">"返回通話"</string>
     <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"正確!"</string>
@@ -686,12 +695,12 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"參閱《使用者指南》或與客戶服務中心聯絡。"</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM 卡已鎖定。"</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"解鎖 SIM 卡中…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"您的解鎖圖案已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
     <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"您的密碼已輸錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
     <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"您的 PIN 已輸錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統就會要求您使用您的 Google 登入資訊解除平板電腦的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次嘗試機會。如果失敗次數超過限制,您就必須登入 Google 帳戶才能解鎖電視。\n\n請過 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統就會要求您使用您的 Google 登入資訊解除手機的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"您的解鎖圖案已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統就會要求您使用您的 Google 登入資訊解除平板電腦的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次嘗試機會。如果失敗次數超過限制,您就必須登入 Google 帳戶才能解鎖電視。\n\n請過 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"您的解鎖圖案已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統就會要求您使用您的 Google 登入資訊解除手機的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"您嘗試解除這個平板電腦的鎖定已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,平板電腦將恢復原廠設定,所有使用者資料都會遺失。"</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"您嘗試解鎖電視已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,電視將恢復原廠設定,所有使用者資料都會遺失。"</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"您嘗試解除這支手機的鎖定已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,手機將恢復原廠設定,所有使用者資料都會遺失。"</string>
@@ -699,7 +708,7 @@
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"您嘗試解鎖電視已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次,電視現在將恢復原廠設定。"</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"您嘗試解除這支手機的鎖定已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次,手機現在將恢復原廠設定。"</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"忘記解鎖圖形?"</string>
+    <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"忘記解鎖圖案?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"帳戶解鎖"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"圖形嘗試次數過多"</string>
     <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"如要解除鎖定,請使用 Google 帳戶登入。"</string>
@@ -712,12 +721,12 @@
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"解除封鎖"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"開啟音效"</string>
     <string name="lockscreen_sound_off_label" msgid="996822825154319026">"關閉音效"</string>
-    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"已開始繪製解鎖圖形"</string>
-    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"已清除解鎖圖形"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"已開始繪製解鎖圖案"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"已清除解鎖圖案"</string>
     <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"已加入 1 格"</string>
     <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"已加入圓點 <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string>
-    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"已畫出解鎖圖形"</string>
-    <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"解鎖圖形區域。"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"已畫出解鎖圖案"</string>
+    <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"解鎖圖案區域。"</string>
     <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s。第 %2$d 個小工具,共 %3$d 個。"</string>
     <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"新增小工具。"</string>
     <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"空白"</string>
@@ -733,7 +742,7 @@
     <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>小工具已刪除。"</string>
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"展開解鎖區域。"</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"滑動解鎖。"</string>
-    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"圖形解鎖。"</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"圖案解鎖。"</string>
     <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"人臉解鎖。"</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN 解鎖。"</string>
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"密碼解鎖。"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"輕觸即可顯示更多選項。"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"輕觸即可停用 USB 偵錯。"</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"要與管理員分享錯誤報告嗎?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"您的 IT 管理員要求您提供錯誤報告,協助排解問題"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"接受"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"拒絕"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"正在取得錯誤報告…"</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"輕觸即可取消"</string>
     <string name="select_input_method" msgid="8547250819326693584">"變更鍵盤"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"選擇鍵盤"</string>
     <string name="show_ime" msgid="9157568568695230830">"顯示輸入法"</string>
@@ -1305,16 +1308,16 @@
     <string name="kg_login_checking_password" msgid="1052685197710252395">"正在檢查帳戶…"</string>
     <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"您的 PIN 已輸錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"您的密碼已輸錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"您的解鎖圖案已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"您嘗試解除這個平板電腦的鎖定已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,平板電腦將恢復原廠設定,所有使用者資料都會遺失。"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"您嘗試解鎖電視已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,電視將恢復原廠設定,所有使用者資料都會遺失。"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"您嘗試解除這支手機的鎖定已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,手機將恢復原廠設定,所有使用者資料都會遺失。"</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"您嘗試解除這個平板電腦的鎖定已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次,平板電腦現在將恢復原廠設定。"</string>
     <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"您嘗試解鎖電視已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次,電視現在將恢復原廠設定。"</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"您嘗試解除這支手機的鎖定已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次,手機現在將恢復原廠設定。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除平板電腦的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"您已畫錯解鎖圖形 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次嘗試機會。如果失敗次數超過限制,您就必須使用電子郵件帳戶才能解鎖電視。\n\n請過 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除手機的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"您的解鎖圖案已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除平板電腦的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次嘗試機會。如果失敗次數超過限制,您就必須使用電子郵件帳戶才能解鎖電視。\n\n請過 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您的解鎖圖案已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除手機的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"移除"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"要調高音量,比建議的音量更大聲嗎?\n\n長時間聆聽高分貝音量可能會使您的聽力受損。"</string>
@@ -1450,7 +1453,7 @@
     <string name="lock_to_app_start" msgid="6643342070839862795">"已固定螢幕"</string>
     <string name="lock_to_app_exit" msgid="8598219838213787430">"已取消固定螢幕"</string>
     <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"取消固定時必須輸入 PIN"</string>
-    <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"取消固定時必須畫出解鎖圖形"</string>
+    <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"取消固定時必須畫出解鎖圖案"</string>
     <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"取消固定時必須輸入密碼"</string>
     <string name="dock_non_resizeble_text" msgid="9156251681042762723">"無法調整這個應用程式的大小,請用雙指捲動該應用程式。"</string>
     <string name="package_installed_device_owner" msgid="8420696545959087545">"已由管理員安裝"</string>
@@ -1524,12 +1527,8 @@
     <string name="default_notification_topic_label" msgid="227586145791870829">"其他"</string>
     <string name="importance_from_topic" msgid="3572280439880023233">"這些通知的重要性由您決定。"</string>
     <string name="importance_from_person" msgid="9160133597262938296">"這則通知涉及特定人士,因此被歸為重要通知。"</string>
-    <!-- no translation found for user_creation_cannot_add (7740333663230045315) -->
-    <skip />
-    <!-- no translation found for user_creation_cannot_add_any_more (6244197709981359266) -->
-    <skip />
-    <!-- no translation found for user_creation_account_exists (4880171855014489789) -->
-    <skip />
-    <!-- no translation found for user_creation_adding (3206420861363021392) -->
-    <skip />
+    <string name="user_creation_cannot_add" msgid="7740333663230045315"><b></b>"「<xliff:g id="APP">%1$s</xliff:g>」正在嘗試新增使用者,但系統目前禁止相關操作。"</string>
+    <string name="user_creation_cannot_add_any_more" msgid="6244197709981359266"><b></b>"「<xliff:g id="APP">%1$s</xliff:g>」正在嘗試新增使用者,但已達到使用者人數上限。"</string>
+    <string name="user_creation_account_exists" msgid="4880171855014489789"><b></b>"「<xliff:g id="APP">%1$s</xliff:g>」正在嘗試新增使用者,但這個裝置上已經有 <xliff:g id="ACCOUNT">%2$s</xliff:g> "<b></b>"這個帳戶。仍要繼續嗎?"</string>
+    <string name="user_creation_adding" msgid="3206420861363021392"><b></b>"「<xliff:g id="APP">%1$s</xliff:g>」正在嘗試為 <xliff:g id="ACCOUNT">%2$s</xliff:g> "<b></b>"這個帳戶新增使用者。要繼續嗎?"</string>
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index b908818..f257f6c 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -211,6 +211,15 @@
     <string name="global_action_bug_report" msgid="7934010578922304799">"Umbiko wephutha"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Thatha umbiko wesiphazamiso"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Lokhu kuzoqoqa ulwazi mayelana nesimo samanje sedivayisi yakho, ukuthumela imilayezo ye-imeyili. Kuzothatha isikhathi esincane kusuka ekuqaleni umbiko wesiphazamiso uze ulungele ukuthunyelwa; sicela ubekezele."</string>
+    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
+    <skip />
+    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
+    <skip />
+    <!-- no translation found for bugreport_option_full_summary (6440582052207304578) -->
+    <skip />
+    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Imodi ethulile"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Umsindo UVALIWE"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Umsindo UVULIWE"</string>
@@ -1032,18 +1041,12 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Thinta ukuze uthole ezinye izinketho."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Ukulungisa iphutha le-USB kuxhunyiwe"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Thinta ukwenza ukuthi ukudibhaga kwe-USB kungasebenzi."</string>
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Yabelana ngombiko wesiphazamisi nomqondisi?"</string>
+    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Umqondisi wakho we-IT ucele umbiko wesiphazamisi ukuze asize ukuxazulula inkinga"</string>
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"YAMUKELA"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"YENQABA"</string>
+    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Ithatha umbiko wesiphazamisi..."</string>
+    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Thinta ukuze ukhansele"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Shintsha ikhibhodi"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Khetha amakhibhodi"</string>
     <string name="show_ime" msgid="9157568568695230830">"Bonisa indlela yokufaka"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 9cc2a2f..655a5fa 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -27,31 +27,59 @@
     <!-- Do not translate. Defines the slots for the right-hand side icons.  That is to say, the
          icons in the status bar that are not notifications. -->
     <string-array name="config_statusBarIcons">
-       <item><xliff:g id="id">managed_profile</xliff:g></item>
-       <item><xliff:g id="id">ime</xliff:g></item>
-       <item><xliff:g id="id">sync_failing</xliff:g></item>
-       <item><xliff:g id="id">sync_active</xliff:g></item>
-       <item><xliff:g id="id">cast</xliff:g></item>
-       <item><xliff:g id="id">hotspot</xliff:g></item>
-       <item><xliff:g id="id">location</xliff:g></item>
-       <item><xliff:g id="id">bluetooth</xliff:g></item>
-       <item><xliff:g id="id">nfc</xliff:g></item>
-       <item><xliff:g id="id">tty</xliff:g></item>
-       <item><xliff:g id="id">speakerphone</xliff:g></item>
-       <item><xliff:g id="id">zen</xliff:g></item>
-       <item><xliff:g id="id">mute</xliff:g></item>
-       <item><xliff:g id="id">volume</xliff:g></item>
-       <item><xliff:g id="id">wifi</xliff:g></item>
-       <item><xliff:g id="id">cdma_eri</xliff:g></item>
-       <item><xliff:g id="id">data_connection</xliff:g></item>
-       <item><xliff:g id="id">phone_evdo_signal</xliff:g></item>
-       <item><xliff:g id="id">phone_signal</xliff:g></item>
-       <item><xliff:g id="id">battery</xliff:g></item>
-       <item><xliff:g id="id">alarm_clock</xliff:g></item>
-       <item><xliff:g id="id">secure</xliff:g></item>
-       <item><xliff:g id="id">clock</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_rotate</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_headset</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_managed_profile</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_ime</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_sync_failing</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_sync_active</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_cast</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_hotspot</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_location</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_bluetooth</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_nfc</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_tty</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_speakerphone</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_zen</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_mute</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_volume</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_wifi</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_cdma_eri</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_data_connection</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_phone_evdo_signal</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_phone_signal</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_battery</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_alarm_clock</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_secure</xliff:g></item>
+        <item><xliff:g id="id">@string/status_bar_clock</xliff:g></item>
     </string-array>
 
+    <string translatable="false" name="status_bar_rotate">rotate</string>
+    <string translatable="false" name="status_bar_headset">headset</string>
+    <string translatable="false" name="status_bar_managed_profile">managed_profile</string>
+    <string translatable="false" name="status_bar_ime">ime</string>
+    <string translatable="false" name="status_bar_sync_failing">sync_failing</string>
+    <string translatable="false" name="status_bar_sync_active">sync_active</string>
+    <string translatable="false" name="status_bar_cast">cast</string>
+    <string translatable="false" name="status_bar_hotspot">hotspot</string>
+    <string translatable="false" name="status_bar_location">location</string>
+    <string translatable="false" name="status_bar_bluetooth">bluetooth</string>
+    <string translatable="false" name="status_bar_nfc">nfc</string>
+    <string translatable="false" name="status_bar_tty">tty</string>
+    <string translatable="false" name="status_bar_speakerphone">speakerphone</string>
+    <string translatable="false" name="status_bar_zen">zen</string>
+    <string translatable="false" name="status_bar_mute">mute</string>
+    <string translatable="false" name="status_bar_volume">volume</string>
+    <string translatable="false" name="status_bar_wifi">wifi</string>
+    <string translatable="false" name="status_bar_cdma_eri">cdma_eri</string>
+    <string translatable="false" name="status_bar_data_connection">data_connection</string>
+    <string translatable="false" name="status_bar_phone_evdo_signal">phone_evdo_signal</string>
+    <string translatable="false" name="status_bar_phone_signal">phone_signal</string>
+    <string translatable="false" name="status_bar_battery">battery</string>
+    <string translatable="false" name="status_bar_alarm_clock">alarm_clock</string>
+    <string translatable="false" name="status_bar_secure">secure</string>
+    <string translatable="false" name="status_bar_clock">clock</string>
+
     <!-- Flag indicating whether the surface flinger has limited
          alpha compositing functionality in hardware.  If set, the window
          manager will disable alpha trasformation in animations where not
@@ -651,17 +679,6 @@
         <!-- rotation: 270 (rotate CW)  --> <item>-25</item> <item>65</item>
     </integer-array>
 
-    <!-- Indicate the name of the window orientation sensor type if present. A
-         window orientation sensor produces values to be used in lieu of the
-         typical, accelerometer based sensor. It must only produce integral
-         values between 0 and 3, inclusive, with each one corresponding to a
-         given rotation:
-            0: 0 degrees of rotation (natural)
-            1: 90 degrees of rotation (rotate CCW)
-            2: 180 degrees of rotation (reverse)
-            3: 270 degrees of rotation (rotate CW) -->
-    <string name="config_orientationSensorType" translatable="false">@null</string>
-
     <!-- Lid switch behavior -->
 
     <!-- The number of degrees to rotate the display when the keyboard is open.
@@ -1977,9 +1994,9 @@
     <string-array name="config_notificationSignalExtractors">
         <item>com.android.server.notification.ValidateNotificationPeople</item>
         <item>com.android.server.notification.TopicPriorityExtractor</item>
+        <item>com.android.server.notification.TopicImportanceExtractor</item>
         <item>com.android.server.notification.NotificationIntrusivenessExtractor</item>
         <item>com.android.server.notification.TopicVisibilityExtractor</item>
-        <item>com.android.server.notification.TopicImportanceExtractor</item>
     </string-array>
 
     <!-- Flag indicating that this device does not rotate and will always remain in its default
diff --git a/core/res/res/values/locale_config.xml b/core/res/res/values/locale_config.xml
index 3cfd9f4..f07fe70 100644
--- a/core/res/res/values/locale_config.xml
+++ b/core/res/res/values/locale_config.xml
@@ -1,21 +1,20 @@
 <?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.
-*/
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
 -->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+<resources>
 
     <string-array translatable="false" name="supported_locales">
         <item>af-NA</item> <!-- Afrikaans (Namibia) -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index f5e9126..eebdd61 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -493,23 +493,18 @@
         time from starting the bug report until it is ready to be sent; please be
         patient.</string>
     <!-- Title in the bugreport dialog for the interactive workflow. [CHAR LIMIT=20] -->
-    <!-- DO NOT TRANSLATE YET: final phrasing still being discussed -->
     <string name="bugreport_option_interactive_title">Interactive report</string>
     <!-- Summary in the bugreport dialog for the interactive workflow. [CHAR LIMIT=NONE] -->
-    <!-- DO NOT TRANSLATE YET: final phrasing still being discussed -->
     <string name="bugreport_option_interactive_summary">Use this under most circumstances.
         It allows you to track progress of the report and enter more details about the problem.
         It might omit some less-used sections that take a long time to report.</string>
     <!-- Title in the bugreport dialog for the full workflow. [CHAR LIMIT=20] -->
-    <!-- DO NOT TRANSLATE YET: final phrasing still being discussed -->
     <string name="bugreport_option_full_title">Full report</string>
     <!-- Summary in the bugreport dialog for the full workflow. [CHAR LIMIT=20] -->
-    <!-- DO NOT TRANSLATE YET: final phrasing still being discussed -->
     <string name="bugreport_option_full_summary">Use this option for minimal interference when
         your device is unresponsive or too slow, or when you need all sections.
         Does not take a screenshot or allow you to enter more details.</string>
     <!--  Toast message informing user in how many seconds a bugreport screenshot will be taken -->
-    <!-- DO NOT TRANSLATE YET: final phrasing still being discussed -->
     <plurals name="bugreport_countdown">
         <item quantity="one">Taking screenshot for bug report in <xliff:g id="number">%d</xliff:g> second.</item>
         <item quantity="other">Taking screenshot for bug report in <xliff:g id="number">%d</xliff:g> seconds.</item>
@@ -2924,10 +2919,10 @@
     <!-- Title of a button to open the settings to enable or disable keyboards, also known as input methods [CHAR LIMIT=30] -->
     <string name="configure_input_methods">Choose keyboards</string>
     <!-- Summary text of a toggle switch to enable/disable use of the IME while a physical
-         keyboard is connected[CHAR LIMIT=25] -->
-    <string name="show_ime">Show input method</string>
-    <!-- Title of the physical keyboard category in the input method selector [CHAR LIMIT=10] -->
-    <string name="hardware">Hardware</string>
+         keyboard is connected -->
+    <string name="show_ime">Keep it on screen while physical keyboard is active</string>
+    <!-- Title of the physical keyboard category in the input method selector [CHAR LIMIT=30] -->
+    <string name="hardware">Show virtual keyboard</string>
 
     <!-- Title of the notification to prompt the user to select a keyboard layout. -->
     <string name="select_keyboard_layout_notification_title">Select keyboard layout</string>
@@ -4151,4 +4146,22 @@
     <string name="user_creation_account_exists"><b><xliff:g id="app" example="Gmail">%1$s</xliff:g></b> is trying to add a new user, but the account <b><xliff:g id="account" example="foobar">%2$s</xliff:g></b> already exists on this device. Proceed anyway?</string>
     <!-- Message to user that app is trying to create user for a specified account. [CHAR LIMIT=none] -->
     <string name="user_creation_adding"><b><xliff:g id="app" example="Gmail">%1$s</xliff:g></b> is trying to add a new user for the account <b><xliff:g id="account" example="foobar">%2$s</xliff:g></b>. Proceed?</string>
+
+    <!-- Locale picker strings -->
+
+    <!-- Title for the language selection screen [CHAR LIMIT=25] -->
+    <string name="language_selection_title">Language preference</string>
+    <!-- Title for the region selection screen [CHAR LIMIT=25] -->
+    <string name="country_selection_title">Region preference</string>
+    <!-- Hint text in a search edit box (used to filter long language / country lists) [CHAR LIMIT=20] -->
+    <string name="search_language_hint">Type language name</string>
+
+    <!-- List section subheader for the language picker, containing a list of suggested languages determined by the default region [CHAR LIMIT=30] -->
+    <string name="language_picker_section_suggested">Suggested</string>
+    <!-- List section subheader for the language picker, containing a list of all languages available [CHAR LIMIT=30] -->
+    <string name="language_picker_section_all">All languages</string>
+
+    <!-- Menu item in the locale menu  [CHAR LIMIT=30] -->
+    <string name="locale_search_menu">Search</string>
+
 </resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 937d83d..d5349b2 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1199,13 +1199,6 @@
         <item name="windowExitAnimation">@anim/fast_fade_out</item>
     </style>
 
-    <!-- Style for the popup window that contains text suggestions. -->
-    <style name="Widget.TextSuggestionsPopupWindow">
-        <item name="dropDownSelector">@drawable/list_selector_background</item>
-        <item name="popupBackground">@drawable/text_edit_suggestions_window</item>
-        <item name="dropDownWidth">wrap_content</item>
-    </style>
-
     <style name="Widget.ActionBar">
         <item name="background">@drawable/action_bar_background</item>
         <item name="displayOptions">useLogo|showHome|showTitle</item>
diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml
index 23ac221..93a5264 100644
--- a/core/res/res/values/styles_device_defaults.xml
+++ b/core/res/res/values/styles_device_defaults.xml
@@ -113,7 +113,6 @@
     <style name="Widget.DeviceDefault.Spinner.DropDown" parent="Widget.Material.Spinner.DropDown"/>
     <style name="Widget.DeviceDefault.StackView" parent="Widget.Material.StackView"/>
     <style name="Widget.DeviceDefault.TextSelectHandle" parent="Widget.Material.TextSelectHandle"/>
-    <style name="Widget.DeviceDefault.TextSuggestionsPopupWindow" parent="Widget.Material.TextSuggestionsPopupWindow"/>
     <style name="Widget.DeviceDefault.TextView.ListSeparator" parent="Widget.Material.TextView.ListSeparator"/>
     <style name="Widget.DeviceDefault.TimePicker" parent="Widget.Material.TimePicker"/>
 
@@ -199,7 +198,6 @@
     <style name="Widget.DeviceDefault.Light.Spinner.DropDown" parent="Widget.Material.Light.Spinner.DropDown"/>
     <style name="Widget.DeviceDefault.Light.TextView.ListSeparator" parent="Widget.Material.Light.TextView.ListSeparator"/>
     <style name="Widget.DeviceDefault.Light.TimePicker" parent="Widget.Material.Light.TimePicker"/>
-    <style name="Widget.DeviceDefault.Light.TextSuggestionsPopupWindow" parent="Widget.Material.Light.TextSuggestionsPopupWindow"/>
 
     <!-- Text Appearance Styles -->
     <style name="TextAppearance.DeviceDefault" parent="TextAppearance.Material"/>
diff --git a/core/res/res/values/styles_holo.xml b/core/res/res/values/styles_holo.xml
index 3cd60df..6c69141 100644
--- a/core/res/res/values/styles_holo.xml
+++ b/core/res/res/values/styles_holo.xml
@@ -401,8 +401,6 @@
 
     <style name="Widget.Holo.TextSelectHandle" parent="Widget.TextSelectHandle" />
 
-    <style name="Widget.Holo.TextSuggestionsPopupWindow" parent="Widget.TextSuggestionsPopupWindow" />
-
     <style name="Widget.Holo.AbsListView" parent="Widget.AbsListView" />
 
     <style name="Widget.Holo.AutoCompleteTextView" parent="Widget.AutoCompleteTextView">
@@ -814,8 +812,6 @@
 
     <style name="Widget.Holo.Light.TextSelectHandle" parent="Widget.TextSelectHandle" />
 
-    <style name="Widget.Holo.Light.TextSuggestionsPopupWindow" parent="Widget.TextSuggestionsPopupWindow" />
-
     <style name="Widget.Holo.Light.AbsListView" parent="Widget.AbsListView" />
 
     <style name="Widget.Holo.Light.AutoCompleteTextView" parent="Widget.AutoCompleteTextView">
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 84d9a2a..7aa0c12 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -570,7 +570,6 @@
 
     <style name="Widget.Material.CheckedTextView" parent="Widget.CheckedTextView" />
     <style name="Widget.Material.TextSelectHandle" parent="Widget.TextSelectHandle"/>
-    <style name="Widget.Material.TextSuggestionsPopupWindow" parent="Widget.TextSuggestionsPopupWindow"/>
     <style name="Widget.Material.AbsListView" parent="Widget.AbsListView"/>
 
     <style name="Widget.Material.AutoCompleteTextView" parent="Widget.AutoCompleteTextView">
@@ -994,7 +993,6 @@
     </style>
 
     <style name="Widget.Material.SuggestionItem" parent="@android:style/TextAppearance.Material.Body1">
-        <item name="background">@color/white</item>
         <item name="alpha">.87</item>
         <item name="textColor">@color/black</item>
         <item name="drawablePadding">8dip</item>
@@ -1016,7 +1014,6 @@
     </style>
 
     <style name="Widget.Material.SuggestionButton" parent="@android:style/TextAppearance.Material.Button">
-        <item name="background">@color/white</item>
         <item name="alpha">.87</item>
         <item name="textColor">#009688</item>
         <item name="drawablePadding">8dip</item>
@@ -1060,7 +1057,6 @@
     <style name="Widget.Material.Light.TextView.SpinnerItem" parent="Widget.Material.TextView.SpinnerItem"/>
     <style name="Widget.Material.Light.CheckedTextView" parent="Widget.Material.CheckedTextView"/>
     <style name="Widget.Material.Light.TextSelectHandle" parent="Widget.Material.TextSelectHandle"/>
-    <style name="Widget.Material.Light.TextSuggestionsPopupWindow" parent="Widget.Material.TextSuggestionsPopupWindow"/>
     <style name="Widget.Material.Light.AbsListView" parent="Widget.Material.AbsListView"/>
     <style name="Widget.Material.Light.AutoCompleteTextView" parent="Widget.Material.AutoCompleteTextView" />
     <style name="Widget.Material.Light.CompoundButton" parent="Widget.Material.CompoundButton"/>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 8a0ab80..9023dd4 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1593,7 +1593,6 @@
   <java-symbol type="string" name="bugreport_option_interactive_title" />
   <java-symbol type="string" name="bugreport_status" />
   <java-symbol type="string" name="bugreport_title" />
-  <java-symbol type="string" name="config_orientationSensorType" />
   <java-symbol type="string" name="faceunlock_multiple_failures" />
   <java-symbol type="string" name="global_action_power_off" />
   <java-symbol type="string" name="global_actions_airplane_mode_off_status" />
@@ -2448,4 +2447,43 @@
   <java-symbol type="style" name="Theme.Material.DayNight.NoActionBar.TranslucentDecor" />
   <java-symbol type="style" name="Theme.Material.DayNight.Panel" />
   <java-symbol type="style" name="Theme.Material.DayNight.DialogWhenLarge.DarkActionBar" />
+
+  <java-symbol type="string" name="status_bar_rotate" />
+  <java-symbol type="string" name="status_bar_headset" />
+  <java-symbol type="string" name="status_bar_managed_profile" />
+  <java-symbol type="string" name="status_bar_ime" />
+  <java-symbol type="string" name="status_bar_sync_failing" />
+  <java-symbol type="string" name="status_bar_sync_active" />
+  <java-symbol type="string" name="status_bar_cast" />
+  <java-symbol type="string" name="status_bar_hotspot" />
+  <java-symbol type="string" name="status_bar_location" />
+  <java-symbol type="string" name="status_bar_bluetooth" />
+  <java-symbol type="string" name="status_bar_nfc" />
+  <java-symbol type="string" name="status_bar_tty" />
+  <java-symbol type="string" name="status_bar_speakerphone" />
+  <java-symbol type="string" name="status_bar_zen" />
+  <java-symbol type="string" name="status_bar_mute" />
+  <java-symbol type="string" name="status_bar_volume" />
+  <java-symbol type="string" name="status_bar_wifi" />
+  <java-symbol type="string" name="status_bar_cdma_eri" />
+  <java-symbol type="string" name="status_bar_data_connection" />
+  <java-symbol type="string" name="status_bar_phone_evdo_signal" />
+  <java-symbol type="string" name="status_bar_phone_signal" />
+  <java-symbol type="string" name="status_bar_battery" />
+  <java-symbol type="string" name="status_bar_alarm_clock" />
+  <java-symbol type="string" name="status_bar_secure" />
+  <java-symbol type="string" name="status_bar_clock" />
+
+  <!-- Locale picker -->
+  <java-symbol type="id" name="l10nWarn" />
+  <java-symbol type="id" name="locale_search_menu" />
+  <java-symbol type="layout" name="language_picker_item" />
+  <java-symbol type="layout" name="language_picker_section_header" />
+  <java-symbol type="menu" name="language_selection_list" />
+  <java-symbol type="string" name="country_selection_title" />
+  <java-symbol type="string" name="language_picker_section_all" />
+  <java-symbol type="string" name="language_picker_section_suggested" />
+  <java-symbol type="string" name="language_selection_title" />
+  <java-symbol type="string" name="search_language_hint" />
+
 </resources>
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index def8659..dd8baa7 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -98,7 +98,6 @@
 
         <!-- Text selection handle attributes -->
         <item name="textSelectHandleWindowStyle">@style/Widget.DeviceDefault.TextSelectHandle</item>
-        <item name="textSuggestionsWindowStyle">@style/Widget.DeviceDefault.TextSuggestionsPopupWindow</item>
 
         <!-- Widget styles -->
         <item name="absListViewStyle">@style/Widget.DeviceDefault.AbsListView</item>
@@ -350,7 +349,6 @@
 
         <!-- Text selection handle attributes -->
         <item name="textSelectHandleWindowStyle">@style/Widget.DeviceDefault.TextSelectHandle</item>
-        <item name="textSuggestionsWindowStyle">@style/Widget.DeviceDefault.Light.TextSuggestionsPopupWindow</item>
 
         <!-- Widget styles -->
         <item name="absListViewStyle">@style/Widget.DeviceDefault.Light.AbsListView</item>
diff --git a/core/res/res/values/themes_holo.xml b/core/res/res/values/themes_holo.xml
index 4cbaacb..34c89fc 100644
--- a/core/res/res/values/themes_holo.xml
+++ b/core/res/res/values/themes_holo.xml
@@ -136,7 +136,6 @@
         <item name="textEditSuggestionItemLayout">@layout/text_edit_suggestion_item</item>
         <item name="textEditSuggestionContainerLayout">@layout/text_edit_suggestion_container</item>
         <item name="textEditSuggestionHighlightStyle">@style/TextAppearance.Holo.SuggestionHighlight</item>
-        <item name="textSuggestionsWindowStyle">@style/Widget.Holo.TextSuggestionsPopupWindow</item>
 
         <!-- Button styles -->
         <item name="buttonStyle">@style/Widget.Holo.Button</item>
@@ -590,7 +589,6 @@
         <item name="textSelectHandleRight">@drawable/text_select_handle_right</item>
         <item name="textSelectHandle">@drawable/text_select_handle_middle</item>
         <item name="textSelectHandleWindowStyle">@style/Widget.Holo.TextSelectHandle</item>
-        <item name="textSuggestionsWindowStyle">@style/Widget.Holo.Light.TextSuggestionsPopupWindow</item>
         <item name="textCursorDrawable">@drawable/text_cursor_holo_light</item>
 
         <!-- Widget styles -->
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index b011094..47892a3 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -223,7 +223,6 @@
         <item name="textSelectHandleWindowStyle">@style/Widget.Material.TextSelectHandle</item>
         <item name="textEditSuggestionItemLayout">@layout/text_edit_suggestion_item_material</item>
         <item name="textEditSuggestionContainerLayout">@layout/text_edit_suggestion_container_material</item>
-        <item name="textSuggestionsWindowStyle">@style/Widget.Material.TextSuggestionsPopupWindow</item>
         <item name="textCursorDrawable">@drawable/text_cursor_material</item>
 
         <!-- Widget styles -->
@@ -588,7 +587,6 @@
         <item name="textEditSuggestionItemLayout">@layout/text_edit_suggestion_item_material</item>
         <item name="textEditSuggestionContainerLayout">@layout/text_edit_suggestion_container_material</item>
         <item name="textEditSuggestionHighlightStyle">@style/TextAppearance.Material.TextSuggestionHighlight</item>
-        <item name="textSuggestionsWindowStyle">@style/Widget.Material.Light.TextSuggestionsPopupWindow</item>
 
         <!-- Widget styles -->
         <item name="absListViewStyle">@style/Widget.Material.Light.AbsListView</item>
diff --git a/core/tests/benchmarks/src/android/text/SpannableStringBuilderBenchmark.java b/core/tests/benchmarks/src/android/text/SpannableStringBuilderBenchmark.java
new file mode 100644
index 0000000..23f8810
--- /dev/null
+++ b/core/tests/benchmarks/src/android/text/SpannableStringBuilderBenchmark.java
@@ -0,0 +1,138 @@
+/*
+ * 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.text;
+
+import com.google.caliper.AfterExperiment;
+import com.google.caliper.BeforeExperiment;
+import com.google.caliper.Benchmark;
+import com.google.caliper.Param;
+
+public class SpannableStringBuilderBenchmark {
+
+    @Param({"android.text.style.ImageSpan",
+            "android.text.style.ParagraphStyle",
+            "android.text.style.CharacterStyle",
+            "java.lang.Object"})
+    private String paramType;
+
+    @Param({"1", "4", "16"})
+    private String paramStringMult;
+
+    private Class clazz;
+    private SpannableStringBuilder builder;
+
+    @BeforeExperiment
+    protected void setUp() throws Exception {
+        clazz = Class.forName(paramType);
+        int strSize = Integer.valueOf(paramStringMult);
+        StringBuilder strBuilder = new StringBuilder();
+        for (int i = 0; i < strSize; i++) {
+            strBuilder.append(TEST_STRING);
+        }
+        builder = new SpannableStringBuilder(Html.fromHtml(strBuilder.toString()));
+    }
+
+    @AfterExperiment
+    protected void tearDown() {
+        builder.clear();
+        builder = null;
+    }
+
+    @Benchmark
+    public void timeGetSpans(int reps) throws Exception {
+        for (int i = 0; i < reps; i++) {
+            builder.getSpans(0, builder.length(), clazz);
+        }
+    }
+
+    //contains 0 ImageSpans, 2 ParagraphSpans, 53 CharacterStyleSpans
+    public static String TEST_STRING =
+            "<p><span><a href=\"http://android.com\">some link</a></span></p>\n" +
+            "<h1 style=\"margin: 0.0px 0.0px 10.0px 0.0px; line-height: 64.0px; font: 62.0px " +
+                    "'Helvetica Neue Light'; color: #000000; \"><span>some title</span></h1>\n" +
+            "<p><span>by <a href=\"http://android.com\"><span>some name</span></a>\n" +
+            "  <a href=\"https://android.com\"><span>some text</span></a></span></p>\n" +
+            "<p><span>some date</span></p>\n" +
+            "<table cellspacing=\"0\" cellpadding=\"0\">\n" +
+            "  <tbody><tr><td valign=\"bottom\">\n" +
+            "        <p><span><blockquote>a paragraph</blockquote></span><br></p>\n" +
+            "  </tbody></tr></td>\n" +
+            "</table>\n" +
+            "<h2 style=\"margin: 0.0px 0.0px 0.0px 0.0px; line-height: 38.0px; font: 26.0px " +
+                    "'Helvetica Neue Light'; color: #262626; -webkit-text-stroke: #262626\">" +
+                    "<span>some header two</span></h2>\n" +
+            "<p><span>Lorem ipsum dolor concludaturque. </span></p>\n" +
+            "<p><span></span><br></p>\n" +
+            "<p><span>Vix te doctus</span></p>\n" +
+            "<p><span><b>Error mel</b></span><span>, est ei. <a href=\"http://andorid.com\">" +
+                    "<span>asda</span></a> ullamcorper eam.</span></p>\n" +
+            "<p><span>adversarium <a href=\"http://android.com\"><span>efficiantur</span></a>, " +
+                    "mea te.</span></p>\n" +
+            "<p><span></span><br></p>\n" +
+            "<h1>Testing display of HTML elements</h1>\n" +
+            "<h2>2nd level heading</h2>\n" +
+            "<p>test paragraph.</p>\n" +
+            "<h3>3rd level heading</h3>\n" +
+            "<p>test paragraph.</p>\n" +
+            "<h4>4th level heading</h4>\n" +
+            "<p>test paragraph.</p>\n" +
+            "<h5>5th level heading</h5>\n" +
+            "<p>test paragraph.</p>\n" +
+            "<h6>6th level heading</h6>\n" +
+            "<p>test paragraph.</p>\n" +
+            "<h2>level elements</h2>\n" +
+            "<p>a normap paragraph(<code>p</code> element).\n" +
+            "  with some <strong>strong</strong>.</p>\n" +
+            "<div>This is a <code>div</code> element. </div>\n" +
+            "<blockquote><p>This is a block quotation with some <em>style</em></p></blockquote>\n" +
+            "<address>an address element</address>\n" +
+            "<h2>Text-level markup</h2>\n" +
+            "<ul>\n" +
+            "  <li> <abbr title=\"Cascading Style Sheets\">CSS</abbr> (an abbreviation;\n" +
+            "    <code>abbr</code> markup used)\n" +
+            "  <li> <acronym title=\"radio detecting and ranging\">radar</acronym>\n" +
+            "  <li> <b>bolded</b>\n" +
+            "  <li> <big>big thing</big>\n" +
+            "  <li> <font size=6>large size</font>\n" +
+            "  <li> <font face=Courier>Courier font</font>\n" +
+            "  <li> <font color=red>red text</font>\n" +
+            "  <li> <cite>Origin of Species</cite>\n" +
+            "  <li> <code>a[i] = b[i] + c[i);</code>\n" +
+            "  <li> some <del>deleted</del> text\n" +
+            "  <li> an <dfn>octet</dfn> is an\n" +
+            "  <li> this is <em>very</em> simple\n" +
+            "  <li> <i lang=\"la\">Homo sapiens</i>\n" +
+            "  <li> some <ins>inserted</ins> text\n" +
+            "  <li> type <kbd>yes</kbd> when\n" +
+            "  <li> <q>Hello!</q>\n" +
+            "  <li> <q>She said <q>Hello!</q></q>\n" +
+            "  <li> <samp>ccc</samp>\n" +
+            "  <li> <small>important</small>\n" +
+            "  <li> <strike>overstruck</strike>\n" +
+            "  <li> <strong>this is highlighted text</strong>\n" +
+            "  <li> <code>sub</code> and\n" +
+            "    <code>sup</code> x<sub>1</sub> and H<sub>2</sub>O\n" +
+            "    M<sup>lle</sup>, 1<sup>st</sup>, e<sup>x</sup>, sin<sup>2</sup> <i>x</i>,\n" +
+            "    e<sup>x<sup>2</sup></sup> and f(x)<sup>g(x)<sup>a+b+c</sup></sup>\n" +
+            "    (where 2 and a+b+c should appear as exponents of exponents).\n" +
+            "  <li> <tt>text in monospace font</tt>\n" +
+            "  <li> <u>underlined</u> text\n" +
+            "  <li> <code>cat</code> <var>filename</var> displays the\n" +
+            "    the <var>filename</var>.\n" +
+            "</ul>\n";
+
+}
diff --git a/core/tests/benchmarks/src/android/text/SpannableStringInternalCopyBenchmark.java b/core/tests/benchmarks/src/android/text/SpannableStringInternalCopyBenchmark.java
new file mode 100644
index 0000000..dc5fed0
--- /dev/null
+++ b/core/tests/benchmarks/src/android/text/SpannableStringInternalCopyBenchmark.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.text;
+
+import com.google.caliper.AfterExperiment;
+import com.google.caliper.BeforeExperiment;
+import com.google.caliper.Benchmark;
+import com.google.caliper.Param;
+
+public class SpannableStringInternalCopyBenchmark {
+
+    @Param({"1", "4", "16"})
+    private String paramStringMult;
+
+    private SpannedString spanned;
+
+    @BeforeExperiment
+    protected void setUp() throws Exception {
+        int strSize = Integer.valueOf(paramStringMult);
+        StringBuilder strBuilder = new StringBuilder();
+        for (int i = 0; i < strSize; i++) {
+            strBuilder.append(SpannableStringBuilderBenchmark.TEST_STRING);
+        }
+        Spanned source = Html.fromHtml(strBuilder.toString());
+        spanned = new SpannedString(source);
+    }
+
+    @AfterExperiment
+    protected void tearDown() {
+        spanned = null;
+    }
+
+    @Benchmark
+    public void timeCopyConstructor(int reps) throws Exception {
+        for (int i = 0; i < reps; i++) {
+            new SpannedString(spanned);
+        }
+    }
+
+    @Benchmark
+    public void timeSubsequence(int reps) throws Exception {
+        for (int i = 0; i < reps; i++) {
+            spanned.subSequence(1, spanned.length()-1);
+        }
+    }
+
+}
diff --git a/core/tests/coretests/src/android/net/NetworkStatsTest.java b/core/tests/coretests/src/android/net/NetworkStatsTest.java
index a470de1..a723977 100644
--- a/core/tests/coretests/src/android/net/NetworkStatsTest.java
+++ b/core/tests/coretests/src/android/net/NetworkStatsTest.java
@@ -16,6 +16,9 @@
 
 package android.net;
 
+import static android.net.NetworkStats.ROAMING_ALL;
+import static android.net.NetworkStats.ROAMING_DEFAULT;
+import static android.net.NetworkStats.ROAMING_ROAMING;
 import static android.net.NetworkStats.SET_DEFAULT;
 import static android.net.NetworkStats.SET_FOREGROUND;
 import static android.net.NetworkStats.SET_DBG_VPN_IN;
@@ -42,62 +45,103 @@
     private static final long TEST_START = 1194220800000L;
 
     public void testFindIndex() throws Exception {
-        final NetworkStats stats = new NetworkStats(TEST_START, 3)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 10)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 11)
-                .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 12);
+        final NetworkStats stats = new NetworkStats(TEST_START, 4)
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1024L, 8L, 0L,
+                        0L, 10)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 0L, 0L, 1024L,
+                        8L, 11)
+                .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1024L, 8L,
+                        1024L, 8L, 12)
+                .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING, 1024L, 8L,
+                        1024L, 8L, 12);
 
-        assertEquals(2, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE));
-        assertEquals(2, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE));
-        assertEquals(0, stats.findIndex(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE));
-        assertEquals(-1, stats.findIndex(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE));
+        assertEquals(3, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING));
+        assertEquals(2, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT));
+        assertEquals(1, stats.findIndex(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT));
+        assertEquals(0, stats.findIndex(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT));
+        assertEquals(-1, stats.findIndex(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT));
     }
 
     public void testFindIndexHinted() {
         final NetworkStats stats = new NetworkStats(TEST_START, 3)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 10)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 11)
-                .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 12)
-                .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 1024L, 8L, 0L, 0L, 10)
-                .addValues(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, 0L, 0L, 1024L, 8L, 11)
-                .addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 12);
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1024L, 8L, 0L,
+                        0L, 10)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 0L, 0L, 1024L,
+                        8L, 11)
+                .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1024L, 8L,
+                        1024L, 8L, 12)
+                .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT, 1024L, 8L,
+                        0L, 0L, 10)
+                .addValues(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, ROAMING_DEFAULT, 0L, 0L, 1024L,
+                        8L, 11)
+                .addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1024L, 8L,
+                        1024L, 8L, 12)
+                .addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING, 1024L, 8L,
+                        1024L, 8L, 12);
 
         // verify that we correctly find across regardless of hinting
         for (int hint = 0; hint < stats.size(); hint++) {
-            assertEquals(0, stats.findIndexHinted(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, hint));
-            assertEquals(1, stats.findIndexHinted(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, hint));
-            assertEquals(2, stats.findIndexHinted(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, hint));
-            assertEquals(3, stats.findIndexHinted(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, hint));
-            assertEquals(4, stats.findIndexHinted(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, hint));
-            assertEquals(5, stats.findIndexHinted(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, hint));
-            assertEquals(-1, stats.findIndexHinted(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE, hint));
+            assertEquals(0, stats.findIndexHinted(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE,
+                    ROAMING_DEFAULT, hint));
+            assertEquals(1, stats.findIndexHinted(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE,
+                    ROAMING_DEFAULT, hint));
+            assertEquals(2, stats.findIndexHinted(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE,
+                    ROAMING_DEFAULT, hint));
+            assertEquals(3, stats.findIndexHinted(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE,
+                    ROAMING_DEFAULT, hint));
+            assertEquals(4, stats.findIndexHinted(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D,
+                    ROAMING_DEFAULT, hint));
+            assertEquals(5, stats.findIndexHinted(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE,
+                    ROAMING_DEFAULT, hint));
+            assertEquals(6, stats.findIndexHinted(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE,
+                    ROAMING_ROAMING, hint));
+            assertEquals(-1, stats.findIndexHinted(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE,
+                    ROAMING_DEFAULT, hint));
         }
     }
 
     public void testAddEntryGrow() throws Exception {
-        final NetworkStats stats = new NetworkStats(TEST_START, 2);
+        final NetworkStats stats = new NetworkStats(TEST_START, 3);
 
         assertEquals(0, stats.size());
-        assertEquals(2, stats.internalSize());
+        assertEquals(3, stats.internalSize());
 
-        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 1L, 1L, 2L, 2L, 3);
-        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 2L, 2L, 2L, 2L, 4);
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1L, 1L, 2L,
+                2L, 3);
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 2L, 2L, 2L,
+                2L, 4);
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING, 3L, 3L, 2L,
+                2L, 5);
 
-        assertEquals(2, stats.size());
-        assertEquals(2, stats.internalSize());
+        assertEquals(3, stats.size());
+        assertEquals(3, stats.internalSize());
 
-        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 3L, 30L, 4L, 40L, 7);
-        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 4L, 40L, 4L, 40L, 8);
-        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 5L, 50L, 5L, 50L, 10);
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 4L, 40L, 4L,
+                40L, 7);
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 5L, 50L, 4L,
+                40L, 8);
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 6L, 60L, 5L,
+                50L, 10);
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING, 7L, 70L, 5L,
+                50L, 11);
 
-        assertEquals(5, stats.size());
-        assertTrue(stats.internalSize() >= 5);
+        assertEquals(7, stats.size());
+        assertTrue(stats.internalSize() >= 7);
 
-        assertValues(stats, 0, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 1L, 1L, 2L, 2L, 3);
-        assertValues(stats, 1, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 2L, 2L, 2L, 2L, 4);
-        assertValues(stats, 2, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 3L, 30L, 4L, 40L, 7);
-        assertValues(stats, 3, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 4L, 40L, 4L, 40L, 8);
-        assertValues(stats, 4, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 5L, 50L, 5L, 50L, 10);
+        assertValues(stats, 0, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1L, 1L,
+                2L, 2L, 3);
+        assertValues(stats, 1, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 2L, 2L,
+                2L, 2L, 4);
+        assertValues(stats, 2, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING, 3L, 3L,
+                2L, 2L, 5);
+        assertValues(stats, 3, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 4L,
+                40L, 4L, 40L, 7);
+        assertValues(stats, 4, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 5L,
+                50L, 4L, 40L, 8);
+        assertValues(stats, 5, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 6L,
+                60L, 5L, 50L, 10);
+        assertValues(stats, 6, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING, 7L,
+                70L, 5L, 50L, 11);
     }
 
     public void testCombineExisting() throws Exception {
@@ -105,16 +149,23 @@
 
         stats.addValues(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 10);
         stats.addValues(TEST_IFACE, 1001, SET_DEFAULT, 0xff, 128L, 1L, 128L, 1L, 2);
-        stats.combineValues(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, -128L, -1L, -128L, -1L, -1);
+        stats.combineValues(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, -128L, -1L,
+                -128L, -1L, -1);
 
-        assertValues(stats, 0, TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, 384L, 3L, 128L, 1L, 9);
-        assertValues(stats, 1, TEST_IFACE, 1001, SET_DEFAULT, 0xff, 128L, 1L, 128L, 1L, 2);
+        assertValues(stats, 0, TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 384L, 3L,
+                128L, 1L, 9);
+        assertValues(stats, 1, TEST_IFACE, 1001, SET_DEFAULT, 0xff, ROAMING_DEFAULT, 128L, 1L, 128L,
+                1L, 2);
 
         // now try combining that should create row
-        stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 3);
-        assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 3);
-        stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 3);
-        assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 256L, 2L, 256L, 2L, 6);
+        stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L,
+                128L, 1L, 3);
+        assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 128L, 1L,
+                128L, 1L, 3);
+        stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L,
+                128L, 1L, 3);
+        assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 256L, 2L,
+                256L, 2L, 6);
     }
 
     public void testSubtractIdenticalData() throws Exception {
@@ -129,8 +180,10 @@
         final NetworkStats result = after.subtract(before);
 
         // identical data should result in zero delta
-        assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0);
-        assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0);
+        assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 0L, 0L, 0L,
+                0L, 0);
+        assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 0L, 0L, 0L,
+                0L, 0);
     }
 
     public void testSubtractIdenticalRows() throws Exception {
@@ -145,8 +198,10 @@
         final NetworkStats result = after.subtract(before);
 
         // expect delta between measurements
-        assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1L, 1L, 2L, 1L, 4);
-        assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 3L, 1L, 4L, 1L, 8);
+        assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1L, 1L, 2L,
+                1L, 4);
+        assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 3L, 1L, 4L,
+                1L, 8);
     }
 
     public void testSubtractNewRows() throws Exception {
@@ -162,9 +217,12 @@
         final NetworkStats result = after.subtract(before);
 
         // its okay to have new rows
-        assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0);
-        assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0);
-        assertValues(result, 2, TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 20);
+        assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 0L, 0L, 0L,
+                0L, 0);
+        assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 0L, 0L, 0L,
+                0L, 0);
+        assertValues(result, 2, TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1024L, 8L,
+                1024L, 8L, 20);
     }
 
     public void testSubtractMissingRows() throws Exception {
@@ -179,7 +237,8 @@
 
         // should silently drop omitted rows
         assertEquals(1, result.size());
-        assertValues(result, 0, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 1L, 2L, 3L, 4L, 0);
+        assertValues(result, 0, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1L,
+                2L, 3L, 4L, 0);
         assertEquals(4L, result.getTotalBytes());
     }
 
@@ -195,7 +254,7 @@
                 .addValues(TEST_IFACE, 101, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
         assertEquals(96L, uidSet.getTotalBytes());
 
-        final NetworkStats uidTag = new NetworkStats(TEST_START, 3)
+        final NetworkStats uidTag = new NetworkStats(TEST_START, 6)
                 .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
                 .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
                 .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L)
@@ -203,6 +262,15 @@
                 .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 16L, 0L, 0L, 0L, 0L)
                 .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L);
         assertEquals(64L, uidTag.getTotalBytes());
+
+        final NetworkStats uidRoaming = new NetworkStats(TEST_START, 3)
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 32L, 0L, 0L, 0L,
+                        0L)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 32L, 0L, 0L, 0L,
+                        0L)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING, 32L, 0L, 0L, 0L,
+                        0L);
+        assertEquals(96L, uidRoaming.getTotalBytes());
     }
 
     public void testGroupedByIfaceEmpty() throws Exception {
@@ -215,62 +283,98 @@
 
     public void testGroupedByIfaceAll() throws Exception {
         final NetworkStats uidStats = new NetworkStats(TEST_START, 3)
-                .addValues(IFACE_ALL, 100, SET_ALL, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
-                .addValues(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, 128L, 8L, 0L, 2L, 20L);
+                .addValues(IFACE_ALL, 100, SET_ALL, TAG_NONE, ROAMING_DEFAULT, 128L, 8L, 0L, 2L,
+                        20L)
+                .addValues(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT, 128L, 8L, 0L,
+                        2L, 20L)
+                .addValues(IFACE_ALL, 101, SET_ALL, TAG_NONE, ROAMING_ROAMING, 128L, 8L, 0L, 2L,
+                        20L);
         final NetworkStats grouped = uidStats.groupedByIface();
 
-        assertEquals(2, uidStats.size());
+        assertEquals(3, uidStats.size());
         assertEquals(1, grouped.size());
 
-        assertValues(grouped, 0, IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE, 256L, 16L, 0L, 4L, 0L);
+        assertValues(grouped, 0, IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE, ROAMING_ALL, 384L, 24L, 0L,
+                6L, 0L);
     }
 
     public void testGroupedByIface() throws Exception {
-        final NetworkStats uidStats = new NetworkStats(TEST_START, 3)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
-                .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L)
-                .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 64L, 4L, 0L, 0L, 0L)
-                .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 512L, 32L, 0L, 0L, 0L)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 128L, 8L, 0L, 0L, 0L);
+        final NetworkStats uidStats = new NetworkStats(TEST_START, 7)
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 128L, 8L, 0L,
+                        2L, 20L)
+                .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 512L, 32L, 0L,
+                        0L, 0L)
+                .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, ROAMING_DEFAULT, 64L, 4L, 0L, 0L,
+                        0L)
+                .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT, 512L, 32L,
+                        0L, 0L, 0L)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 128L, 8L, 0L,
+                        0L, 0L)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, ROAMING_DEFAULT, 128L, 8L, 0L, 0L,
+                        0L)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING, 128L, 8L, 0L,
+                        0L, 0L);
 
         final NetworkStats grouped = uidStats.groupedByIface();
 
-        assertEquals(6, uidStats.size());
+        assertEquals(7, uidStats.size());
 
         assertEquals(2, grouped.size());
-        assertValues(grouped, 0, TEST_IFACE, UID_ALL, SET_ALL, TAG_NONE, 256L, 16L, 0L, 2L, 0L);
-        assertValues(grouped, 1, TEST_IFACE2, UID_ALL, SET_ALL, TAG_NONE, 1024L, 64L, 0L, 0L, 0L);
+        assertValues(grouped, 0, TEST_IFACE, UID_ALL, SET_ALL, TAG_NONE, ROAMING_ALL, 384L, 24L, 0L,
+                2L, 0L);
+        assertValues(grouped, 1, TEST_IFACE2, UID_ALL, SET_ALL, TAG_NONE, ROAMING_ALL, 1024L, 64L,
+                0L, 0L, 0L);
     }
 
     public void testAddAllValues() {
         final NetworkStats first = new NetworkStats(TEST_START, 5)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
-                .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 32L, 0L, 0L, 0L,
+                        0L)
+                .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT, 32L, 0L, 0L,
+                        0L, 0L)
+                .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_ROAMING, 32L, 0L, 0L,
+                        0L, 0L);
 
         final NetworkStats second = new NetworkStats(TEST_START, 2)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
-                .addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 32L, 0L, 0L, 0L,
+                        0L)
+                .addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 32L, 0L,
+                        0L, 0L, 0L)
+                .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_ROAMING, 32L, 0L, 0L,
+                        0L, 0L);
 
         first.combineAllValues(second);
 
-        assertEquals(3, first.size());
-        assertValues(first, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 64L, 0L, 0L, 0L, 0L);
-        assertValues(first, 1, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
-        assertValues(first, 2, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
+        assertEquals(4, first.size());
+        assertValues(first, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 64L, 0L, 0L,
+                0L, 0L);
+        assertValues(first, 1, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT, 32L, 0L,
+                0L, 0L, 0L);
+        assertValues(first, 2, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_ROAMING, 64L, 0L,
+                0L, 0L, 0L);
+        assertValues(first, 3, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 32L,
+                0L, 0L, 0L, 0L);
     }
 
     public void testGetTotal() {
-        final NetworkStats stats = new NetworkStats(TEST_START, 3)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
-                .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L)
-                .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 64L, 4L, 0L, 0L, 0L)
-                .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 512L, 32L, 0L, 0L, 0L)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 128L, 8L, 0L, 0L, 0L);
+        final NetworkStats stats = new NetworkStats(TEST_START, 7)
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 128L, 8L, 0L,
+                        2L, 20L)
+                .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 512L, 32L, 0L,
+                        0L, 0L)
+                .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, ROAMING_DEFAULT, 64L, 4L, 0L, 0L,
+                        0L)
+                .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT, 512L, 32L,
+                        0L, 0L, 0L)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 128L, 8L, 0L,
+                        0L, 0L)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, ROAMING_DEFAULT, 128L, 8L, 0L, 0L,
+                        0L)
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING, 128L, 8L, 0L,
+                        0L, 0L);
 
-        assertValues(stats.getTotal(null), 1280L, 80L, 0L, 2L, 20L);
-        assertValues(stats.getTotal(null, 100), 1152L, 72L, 0L, 2L, 20L);
+        assertValues(stats.getTotal(null), 1408L, 88L, 0L, 2L, 20L);
+        assertValues(stats.getTotal(null, 100), 1280L, 80L, 0L, 2L, 20L);
         assertValues(stats.getTotal(null, 101), 128L, 8L, 0L, 0L, 0L);
 
         final HashSet<String> ifaces = Sets.newHashSet();
@@ -292,8 +396,10 @@
         final NetworkStats after = before.withoutUids(new int[] { 100 });
         assertEquals(6, before.size());
         assertEquals(2, after.size());
-        assertValues(after, 0, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L);
-        assertValues(after, 1, TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 128L, 8L, 0L, 0L, 0L);
+        assertValues(after, 0, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 128L, 8L,
+                0L, 0L, 0L);
+        assertValues(after, 1, TEST_IFACE, 101, SET_DEFAULT, 0xF00D, ROAMING_DEFAULT, 128L, 8L, 0L,
+                0L, 0L);
     }
 
     public void testClone() throws Exception {
@@ -351,76 +457,83 @@
         assertEquals(21, delta.size());
 
         // tunIface and TEST_IFACE entries are not changed.
-        assertValues(delta, 0, tunIface, 10100, SET_DEFAULT, TAG_NONE,
+        assertValues(delta, 0, tunIface, 10100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
                 39605L, 46L, 12259L, 55L, 0L);
-        assertValues(delta, 1, tunIface, 10100, SET_FOREGROUND, TAG_NONE, 0L, 0L, 0L, 0L, 0L);
-        assertValues(delta, 2, tunIface, 10120, SET_DEFAULT, TAG_NONE,
+        assertValues(delta, 1, tunIface, 10100, SET_FOREGROUND, TAG_NONE,  ROAMING_DEFAULT, 0L, 0L,
+                0L, 0L, 0L);
+        assertValues(delta, 2, tunIface, 10120, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
                 72667L, 197L, 43909L, 241L, 0L);
-        assertValues(delta, 3, tunIface, 10120, SET_FOREGROUND, TAG_NONE,
+        assertValues(delta, 3, tunIface, 10120, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT,
                 9297L, 17L, 4128L, 21L, 0L);
-        assertValues(delta, 4, tunIface, tunUid, SET_DEFAULT, TAG_NONE,
+        assertValues(delta, 4, tunIface, tunUid, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
                 4983L, 10L, 1801L, 12L, 0L);
-        assertValues(delta, 5, tunIface, tunUid, SET_FOREGROUND, TAG_NONE, 0L, 0L, 0L, 0L, 0L);
-        assertValues(delta, 6, tunIface, 10120, SET_DEFAULT, testTag1,
+        assertValues(delta, 5, tunIface, tunUid, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT, 0L, 0L,
+                0L, 0L, 0L);
+        assertValues(delta, 6, tunIface, 10120, SET_DEFAULT, testTag1, ROAMING_DEFAULT,
                 21691L, 41L, 13820L, 51L, 0L);
-        assertValues(delta, 7, tunIface, 10120, SET_FOREGROUND, testTag1, 1281L, 2L, 665L, 2L, 0L);
-        assertValues(delta, 8, TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, 1685L, 5L, 2070L, 6L, 0L);
+        assertValues(delta, 7, tunIface, 10120, SET_FOREGROUND, testTag1, ROAMING_DEFAULT, 1281L,
+                2L, 665L, 2L, 0L);
+        assertValues(delta, 8, TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1685L, 5L,
+                2070L, 6L, 0L);
 
         // Existing underlying Iface entries are updated
-        assertValues(delta, 9, underlyingIface, 10100, SET_DEFAULT, TAG_NONE,
+        assertValues(delta, 9, underlyingIface, 10100, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
                 44783L, 54L, 13829L, 60L, 0L);
-        assertValues(delta, 10, underlyingIface, 10100, SET_FOREGROUND, TAG_NONE,
+        assertValues(delta, 10, underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT,
                 0L, 0L, 0L, 0L, 0L);
 
         // VPN underlying Iface entries are updated
-        assertValues(delta, 11, underlyingIface, tunUid, SET_DEFAULT, TAG_NONE,
+        assertValues(delta, 11, underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
                 28304L, 27L, 1719L, 12L, 0L);
-        assertValues(delta, 12, underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE,
+        assertValues(delta, 12, underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT,
                 0L, 0L, 0L, 0L, 0L);
 
         // New entries are added for new application's underlying Iface traffic
-        assertContains(delta, underlyingIface, 10120, SET_DEFAULT, TAG_NONE,
-                72667L, 197L, 41872l, 219L, 0L);
-        assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, TAG_NONE,
+        assertContains(delta, underlyingIface, 10120, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT,
+                72667L, 197L, 41872L, 219L, 0L);
+        assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT,
                 9297L, 17L, 3936, 19L, 0L);
-        assertContains(delta, underlyingIface, 10120, SET_DEFAULT, testTag1,
+        assertContains(delta, underlyingIface, 10120, SET_DEFAULT, testTag1, ROAMING_DEFAULT,
                 21691L, 41L, 13179L, 46L, 0L);
-        assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, testTag1,
+        assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, testTag1, ROAMING_DEFAULT,
                 1281L, 2L, 634L, 1L, 0L);
 
         // New entries are added for debug purpose
-        assertContains(delta, underlyingIface, 10100, SET_DBG_VPN_IN, TAG_NONE,
+        assertContains(delta, underlyingIface, 10100, SET_DBG_VPN_IN, TAG_NONE, ROAMING_DEFAULT,
                 39605L, 46L, 11690, 49, 0);
-        assertContains(delta, underlyingIface, 10120, SET_DBG_VPN_IN, TAG_NONE,
+        assertContains(delta, underlyingIface, 10120, SET_DBG_VPN_IN, TAG_NONE, ROAMING_DEFAULT,
                 81964, 214, 45808, 238, 0);
-        assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_IN, TAG_NONE,
+        assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_IN, TAG_NONE, ROAMING_DEFAULT,
                 4983, 10, 1717, 10, 0);
-        assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_OUT, TAG_NONE,
+        assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_OUT, TAG_NONE, ROAMING_ALL,
                 126552, 270, 59215, 297, 0);
 
     }
 
     private static void assertContains(NetworkStats stats,  String iface, int uid, int set,
-            int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
-        int index = stats.findIndex(iface, uid, set, tag);
+            int tag, int roaming, long rxBytes, long rxPackets, long txBytes, long txPackets,
+            long operations) {
+        int index = stats.findIndex(iface, uid, set, tag, roaming);
         assertTrue(index != -1);
-        assertValues(stats, index, iface, uid, set, tag,
+        assertValues(stats, index, iface, uid, set, tag, roaming,
                 rxBytes, rxPackets, txBytes, txPackets, operations);
     }
 
     private static void assertValues(NetworkStats stats, int index, String iface, int uid, int set,
-            int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
+            int tag, int roaming, long rxBytes, long rxPackets, long txBytes, long txPackets,
+            long operations) {
         final NetworkStats.Entry entry = stats.getValues(index, null);
-        assertValues(entry, iface, uid, set, tag);
+        assertValues(entry, iface, uid, set, tag, roaming);
         assertValues(entry, rxBytes, rxPackets, txBytes, txPackets, operations);
     }
 
     private static void assertValues(
-            NetworkStats.Entry entry, String iface, int uid, int set, int tag) {
+            NetworkStats.Entry entry, String iface, int uid, int set, int tag, int roaming) {
         assertEquals(iface, entry.iface);
         assertEquals(uid, entry.uid);
         assertEquals(set, entry.set);
         assertEquals(tag, entry.tag);
+        assertEquals(roaming, entry.roaming);
     }
 
     private static void assertValues(NetworkStats.Entry entry, long rxBytes, long rxPackets,
diff --git a/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java b/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
index d3dd01a..12a75b8 100644
--- a/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
+++ b/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.net;
 
+import static android.net.NetworkStats.ROAMING_DEFAULT;
 import static android.net.NetworkStats.SET_ALL;
 import static android.net.NetworkStats.SET_DEFAULT;
 import static android.net.NetworkStats.SET_FOREGROUND;
@@ -156,7 +157,7 @@
 
     private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set,
             int tag, long rxBytes, long txBytes) {
-        final int i = stats.findIndex(iface, uid, set, tag);
+        final int i = stats.findIndex(iface, uid, set, tag, ROAMING_DEFAULT);
         final NetworkStats.Entry entry = stats.getValues(i, null);
         assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
         assertEquals("unexpected txBytes", txBytes, entry.txBytes);
@@ -164,7 +165,7 @@
 
     private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set,
             int tag, long rxBytes, long rxPackets, long txBytes, long txPackets) {
-        final int i = stats.findIndex(iface, uid, set, tag);
+        final int i = stats.findIndex(iface, uid, set, tag, ROAMING_DEFAULT);
         final NetworkStats.Entry entry = stats.getValues(i, null);
         assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
         assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index 731bf42..961d0eb 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -341,15 +341,9 @@
     <family lang="ko">
         <font weight="400" style="normal" index="1">NotoSansCJK-Regular.ttc</font>
     </family>
-    <family>
-        <font weight="400" style="normal">NanumGothic.ttf</font>
-    </family>
     <family lang="und-Zsye">
         <font weight="400" style="normal">NotoColorEmoji.ttf</font>
     </family>
-    <family>
-        <font weight="400" style="normal">DroidSansFallback.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/include/androidfw/LocaleData.h b/include/androidfw/LocaleData.h
new file mode 100644
index 0000000..add0ab5
--- /dev/null
+++ b/include/androidfw/LocaleData.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBS_UTILS_LOCALE_DATA_H
+#define _LIBS_UTILS_LOCALE_DATA_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace android {
+
+int localeDataCompareRegions(
+        const char* left_region, const char* right_region,
+        const char* requested_language, const char* requested_script,
+        const char* requested_region);
+
+void localeDataComputeScript(char out[4], const char* language, const char* region);
+
+} // namespace android
+
+#endif // _LIBS_UTILS_LOCALE_DATA_H
diff --git a/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h
index 428a2b8..88fecce 100644
--- a/include/androidfw/ResourceTypes.h
+++ b/include/androidfw/ResourceTypes.h
@@ -21,6 +21,7 @@
 #define _LIBS_UTILS_RESOURCE_TYPES_H
 
 #include <androidfw/Asset.h>
+#include <androidfw/LocaleData.h>
 #include <utils/ByteOrder.h>
 #include <utils/Errors.h>
 #include <utils/String16.h>
@@ -1127,8 +1128,9 @@
     // configuration. (eg. Hant, Latn, etc.). Interpreted in conjunction with
     // the locale field.
     char localeScript[4];
+    bool localeScriptWasProvided;
 
-    // A single BCP-47 variant subtag. Will vary in length between 5 and 8
+    // A single BCP-47 variant subtag. Will vary in length between 4 and 8
     // chars. Interpreted in conjunction with the locale field.
     char localeVariant[8];
 
@@ -1228,10 +1230,15 @@
 
     inline void clearLocale() {
         locale = 0;
+        localeScriptWasProvided = false;
         memset(localeScript, 0, sizeof(localeScript));
         memset(localeVariant, 0, sizeof(localeVariant));
     }
 
+    inline void computeScript() {
+        localeDataComputeScript(localeScript, language, country);
+    }
+
     // Get the 2 or 3 letter language code of this configuration. Trailing
     // bytes are set to '\0'.
     size_t unpackLanguage(char language[4]) const;
@@ -1255,6 +1262,12 @@
     // and 0 if they're equally specific.
     int isLocaleMoreSpecificThan(const ResTable_config &o) const;
 
+    // Return true if 'this' is a better locale match than 'o' for the
+    // 'requested' configuration. Similar to isBetterThan(), this assumes that
+    // match() has already been used to remove any configurations that don't
+    // match the requested configuration at all.
+    bool isLocaleBetterThan(const ResTable_config& o, const ResTable_config* requested) const;
+
     String8 toString() const;
 };
 
diff --git a/libs/androidfw/Android.mk b/libs/androidfw/Android.mk
index 4c2d35a..6bbfcd2 100644
--- a/libs/androidfw/Android.mk
+++ b/libs/androidfw/Android.mk
@@ -21,6 +21,7 @@
     Asset.cpp \
     AssetDir.cpp \
     AssetManager.cpp \
+    LocaleData.cpp \
     misc.cpp \
     ObbFile.cpp \
     ResourceTypes.cpp \
diff --git a/libs/androidfw/LocaleData.cpp b/libs/androidfw/LocaleData.cpp
new file mode 100644
index 0000000..c0c3ab8
--- /dev/null
+++ b/libs/androidfw/LocaleData.cpp
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+
+#include <androidfw/LocaleData.h>
+
+namespace android {
+
+#include "LocaleDataTables.cpp"
+
+inline uint32_t packLocale(const char* language, const char* region) {
+    return (((uint8_t) language[0]) << 24u) | (((uint8_t) language[1]) << 16u) |
+           (((uint8_t) region[0]) << 8u) | ((uint8_t) region[1]);
+}
+
+inline uint32_t dropRegion(uint32_t packed_locale) {
+    return packed_locale & 0xFFFF0000lu;
+}
+
+inline bool hasRegion(uint32_t packed_locale) {
+    return (packed_locale & 0x0000FFFFlu) != 0;
+}
+
+const size_t SCRIPT_LENGTH = 4;
+const size_t SCRIPT_PARENTS_COUNT = sizeof(SCRIPT_PARENTS)/sizeof(SCRIPT_PARENTS[0]);
+const uint32_t PACKED_ROOT = 0; // to represent the root locale
+
+uint32_t findParent(uint32_t packed_locale, const char* script) {
+    if (hasRegion(packed_locale)) {
+        for (size_t i = 0; i < SCRIPT_PARENTS_COUNT; i++) {
+            if (memcmp(script, SCRIPT_PARENTS[i].script, SCRIPT_LENGTH) == 0) {
+                auto map = SCRIPT_PARENTS[i].map;
+                auto lookup_result = map->find(packed_locale);
+                if (lookup_result != map->end()) {
+                    return lookup_result->second;
+                }
+                break;
+            }
+        }
+        return dropRegion(packed_locale);
+    }
+    return PACKED_ROOT;
+}
+
+// Find the ancestors of a locale, and fill 'out' with it (assumes out has enough
+// space). If any of the members of stop_list was seen, write it in the
+// output but stop afterwards.
+//
+// This also outputs the index of the last written ancestor in the stop_list
+// to stop_list_index, which will be -1 if it is not found in the stop_list.
+//
+// Returns the number of ancestors written in the output, which is always
+// at least one.
+size_t findAncestors(uint32_t* out, ssize_t* stop_list_index,
+                     uint32_t packed_locale, const char* script,
+                     const uint32_t* stop_list, size_t stop_set_length) {
+    uint32_t ancestor = packed_locale;
+    size_t count = 0;
+    do {
+        out[count++] = ancestor;
+        for (size_t i = 0; i < stop_set_length; i++) {
+            if (stop_list[i] == ancestor) {
+                *stop_list_index = (ssize_t) i;
+                return count;
+            }
+        }
+        ancestor = findParent(ancestor, script);
+    } while (ancestor != PACKED_ROOT);
+    *stop_list_index = (ssize_t) -1;
+    return count;
+}
+
+size_t findDistance(uint32_t supported,
+                    const char* script,
+                    const uint32_t* request_ancestors,
+                    size_t request_ancestors_count) {
+    uint32_t supported_ancestors[MAX_PARENT_DEPTH+1];
+    ssize_t request_ancestors_index;
+    const size_t supported_ancestor_count = findAncestors(
+            supported_ancestors, &request_ancestors_index,
+            supported, script,
+            request_ancestors, request_ancestors_count);
+    // Since both locales share the same root, there will always be a shared
+    // ancestor, so the distance in the parent tree is the sum of the distance
+    // of 'supported' to the lowest common ancestor (number of ancestors
+    // written for 'supported' minus 1) plus the distance of 'request' to the
+    // lowest common ancestor (the index of the ancestor in request_ancestors).
+    return supported_ancestor_count + request_ancestors_index - 1;
+}
+
+inline bool isRepresentative(uint32_t language_and_region, const char* script) {
+    const uint64_t packed_locale = (
+            (((uint64_t) language_and_region) << 32u) |
+            (((uint64_t) script[0]) << 24u) |
+            (((uint64_t) script[1]) << 16u) |
+            (((uint64_t) script[2]) <<  8u) |
+            ((uint64_t) script[3]));
+
+    return (REPRESENTATIVE_LOCALES.count(packed_locale) != 0);
+}
+
+int localeDataCompareRegions(
+        const char* left_region, const char* right_region,
+        const char* requested_language, const char* requested_script,
+        const char* requested_region) {
+
+    if (left_region[0] == right_region[0] && left_region[1] == right_region[1]) {
+        return 0;
+    }
+    const uint32_t left = packLocale(requested_language, left_region);
+    const uint32_t right = packLocale(requested_language, right_region);
+    const uint32_t request = packLocale(requested_language, requested_region);
+
+    uint32_t request_ancestors[MAX_PARENT_DEPTH+1];
+    ssize_t left_right_index;
+    // Find the parents of the request, but stop as soon as we saw left or right
+    const uint32_t left_and_right[] = {left, right};
+    const size_t ancestor_count = findAncestors(
+            request_ancestors, &left_right_index,
+            request, requested_script,
+            left_and_right, sizeof(left_and_right)/sizeof(left_and_right[0]));
+    if (left_right_index == 0) { // We saw left earlier
+        return 1;
+    }
+    if (left_right_index == 1) { // We saw right earlier
+        return -1;
+    }
+
+    // If we are here, neither left nor right are an ancestor of the
+    // request. This means that all the ancestors have been computed and
+    // the last ancestor is just the language by itself. We will use the
+    // distance in the parent tree for determining the better match.
+    const size_t left_distance = findDistance(
+            left, requested_script, request_ancestors, ancestor_count);
+    const size_t right_distance = findDistance(
+            right, requested_script, request_ancestors, ancestor_count);
+    if (left_distance != right_distance) {
+        return (int) right_distance - (int) left_distance; // smaller distance is better
+    }
+
+    // If we are here, left and right are equidistant from the request. We will
+    // try and see if any of them is a representative locale.
+    const bool left_is_representative = isRepresentative(left, requested_script);
+    const bool right_is_representative = isRepresentative(right, requested_script);
+    if (left_is_representative != right_is_representative) {
+        return (int) left_is_representative - (int) right_is_representative;
+    }
+
+    // We have no way of figuring out which locale is a better match. For
+    // the sake of stability, we consider the locale with the lower region
+    // code (in dictionary order) better, with two-letter codes before
+    // three-digit codes (since two-letter codes are more specific).
+    return (int64_t) right - (int64_t) left;
+}
+
+void localeDataComputeScript(char out[4], const char* language, const char* region) {
+    if (language[0] == '\0') {
+        memset(out, '\0', SCRIPT_LENGTH);
+        return;
+    }
+    uint32_t lookup_key = packLocale(language, region);
+    auto lookup_result = LIKELY_SCRIPTS.find(lookup_key);
+    if (lookup_result == LIKELY_SCRIPTS.end()) {
+        // We couldn't find the locale. Let's try without the region
+        if (region[0] != '\0') {
+            lookup_key = dropRegion(lookup_key);
+            lookup_result = LIKELY_SCRIPTS.find(lookup_key);
+            if (lookup_result != LIKELY_SCRIPTS.end()) {
+                memcpy(out, SCRIPT_CODES[lookup_result->second], SCRIPT_LENGTH);
+                return;
+            }
+        }
+        // We don't know anything about the locale
+        memset(out, '\0', SCRIPT_LENGTH);
+        return;
+    } else {
+        // We found the locale.
+        memcpy(out, SCRIPT_CODES[lookup_result->second], SCRIPT_LENGTH);
+    }
+}
+
+} // namespace android
diff --git a/libs/androidfw/LocaleDataTables.cpp b/libs/androidfw/LocaleDataTables.cpp
new file mode 100644
index 0000000..1ac5085
--- /dev/null
+++ b/libs/androidfw/LocaleDataTables.cpp
@@ -0,0 +1,1701 @@
+// Auto-generated by frameworks/base/tools/localedata/extract_icu_data.py
+
+const char SCRIPT_CODES[][4] = {
+    /* 0  */ {'A', 'h', 'o', 'm'},
+    /* 1  */ {'A', 'r', 'a', 'b'},
+    /* 2  */ {'A', 'r', 'm', 'i'},
+    /* 3  */ {'A', 'r', 'm', 'n'},
+    /* 4  */ {'A', 'v', 's', 't'},
+    /* 5  */ {'B', 'a', 'm', 'u'},
+    /* 6  */ {'B', 'a', 's', 's'},
+    /* 7  */ {'B', 'e', 'n', 'g'},
+    /* 8  */ {'B', 'r', 'a', 'h'},
+    /* 9  */ {'C', 'a', 'n', 's'},
+    /* 10 */ {'C', 'a', 'r', 'i'},
+    /* 11 */ {'C', 'h', 'a', 'm'},
+    /* 12 */ {'C', 'h', 'e', 'r'},
+    /* 13 */ {'C', 'o', 'p', 't'},
+    /* 14 */ {'C', 'p', 'r', 't'},
+    /* 15 */ {'C', 'y', 'r', 'l'},
+    /* 16 */ {'D', 'e', 'v', 'a'},
+    /* 17 */ {'E', 'g', 'y', 'p'},
+    /* 18 */ {'E', 't', 'h', 'i'},
+    /* 19 */ {'G', 'e', 'o', 'r'},
+    /* 20 */ {'G', 'o', 't', 'h'},
+    /* 21 */ {'G', 'r', 'e', 'k'},
+    /* 22 */ {'G', 'u', 'j', 'r'},
+    /* 23 */ {'G', 'u', 'r', 'u'},
+    /* 24 */ {'H', 'a', 'n', 's'},
+    /* 25 */ {'H', 'a', 'n', 't'},
+    /* 26 */ {'H', 'a', 't', 'r'},
+    /* 27 */ {'H', 'e', 'b', 'r'},
+    /* 28 */ {'H', 'l', 'u', 'w'},
+    /* 29 */ {'H', 'm', 'n', 'g'},
+    /* 30 */ {'I', 't', 'a', 'l'},
+    /* 31 */ {'J', 'p', 'a', 'n'},
+    /* 32 */ {'K', 'a', 'l', 'i'},
+    /* 33 */ {'K', 'a', 'n', 'a'},
+    /* 34 */ {'K', 'h', 'a', 'r'},
+    /* 35 */ {'K', 'h', 'm', 'r'},
+    /* 36 */ {'K', 'n', 'd', 'a'},
+    /* 37 */ {'K', 'o', 'r', 'e'},
+    /* 38 */ {'K', 't', 'h', 'i'},
+    /* 39 */ {'L', 'a', 'n', 'a'},
+    /* 40 */ {'L', 'a', 'o', 'o'},
+    /* 41 */ {'L', 'a', 't', 'n'},
+    /* 42 */ {'L', 'e', 'p', 'c'},
+    /* 43 */ {'L', 'i', 'n', 'a'},
+    /* 44 */ {'L', 'i', 's', 'u'},
+    /* 45 */ {'L', 'y', 'c', 'i'},
+    /* 46 */ {'L', 'y', 'd', 'i'},
+    /* 47 */ {'M', 'a', 'n', 'd'},
+    /* 48 */ {'M', 'a', 'n', 'i'},
+    /* 49 */ {'M', 'e', 'r', 'c'},
+    /* 50 */ {'M', 'l', 'y', 'm'},
+    /* 51 */ {'M', 'o', 'n', 'g'},
+    /* 52 */ {'M', 'r', 'o', 'o'},
+    /* 53 */ {'M', 'y', 'm', 'r'},
+    /* 54 */ {'N', 'a', 'r', 'b'},
+    /* 55 */ {'N', 'k', 'o', 'o'},
+    /* 56 */ {'O', 'g', 'a', 'm'},
+    /* 57 */ {'O', 'r', 'k', 'h'},
+    /* 58 */ {'O', 'r', 'y', 'a'},
+    /* 59 */ {'P', 'a', 'u', 'c'},
+    /* 60 */ {'P', 'h', 'l', 'i'},
+    /* 61 */ {'P', 'h', 'n', 'x'},
+    /* 62 */ {'P', 'l', 'r', 'd'},
+    /* 63 */ {'P', 'r', 't', 'i'},
+    /* 64 */ {'R', 'u', 'n', 'r'},
+    /* 65 */ {'S', 'a', 'm', 'r'},
+    /* 66 */ {'S', 'a', 'r', 'b'},
+    /* 67 */ {'S', 'a', 'u', 'r'},
+    /* 68 */ {'S', 'g', 'n', 'w'},
+    /* 69 */ {'S', 'i', 'n', 'h'},
+    /* 70 */ {'S', 'o', 'r', 'a'},
+    /* 71 */ {'S', 'y', 'r', 'c'},
+    /* 72 */ {'T', 'a', 'l', 'e'},
+    /* 73 */ {'T', 'a', 'l', 'u'},
+    /* 74 */ {'T', 'a', 'm', 'l'},
+    /* 75 */ {'T', 'a', 'v', 't'},
+    /* 76 */ {'T', 'e', 'l', 'u'},
+    /* 77 */ {'T', 'f', 'n', 'g'},
+    /* 78 */ {'T', 'h', 'a', 'a'},
+    /* 79 */ {'T', 'h', 'a', 'i'},
+    /* 80 */ {'T', 'i', 'b', 't'},
+    /* 81 */ {'U', 'g', 'a', 'r'},
+    /* 82 */ {'V', 'a', 'i', 'i'},
+    /* 83 */ {'X', 'p', 'e', 'o'},
+    /* 84 */ {'X', 's', 'u', 'x'},
+    /* 85 */ {'Y', 'i', 'i', 'i'},
+    /* 86 */ {'~', '~', '~', 'A'},
+    /* 87 */ {'~', '~', '~', 'B'},
+};
+
+
+const std::unordered_map<uint32_t, uint8_t> LIKELY_SCRIPTS({
+    {0x61610000u, 41u}, // aa -> Latn
+    {0x61620000u, 15u}, // ab -> Cyrl
+    {0xC4200000u, 41u}, // abr -> Latn
+    {0x90400000u, 41u}, // ace -> Latn
+    {0x9C400000u, 41u}, // ach -> Latn
+    {0x80600000u, 41u}, // ada -> Latn
+    {0xE0600000u, 15u}, // ady -> Cyrl
+    {0x61650000u,  4u}, // ae -> Avst
+    {0x84800000u,  1u}, // aeb -> Arab
+    {0x61660000u, 41u}, // af -> Latn
+    {0xC0C00000u, 41u}, // agq -> Latn
+    {0xB8E00000u,  0u}, // aho -> Ahom
+    {0x616B0000u, 41u}, // ak -> Latn
+    {0xA9400000u, 84u}, // akk -> Xsux
+    {0xB5600000u, 41u}, // aln -> Latn
+    {0xCD600000u, 15u}, // alt -> Cyrl
+    {0x616D0000u, 18u}, // am -> Ethi
+    {0xB9800000u, 41u}, // amo -> Latn
+    {0xE5C00000u, 41u}, // aoz -> Latn
+    {0x61720000u,  1u}, // ar -> Arab
+    {0x61725842u, 87u}, // ar-XB -> ~~~B
+    {0x8A200000u,  2u}, // arc -> Armi
+    {0xB6200000u, 41u}, // arn -> Latn
+    {0xBA200000u, 41u}, // aro -> Latn
+    {0xC2200000u,  1u}, // arq -> Arab
+    {0xE2200000u,  1u}, // ary -> Arab
+    {0xE6200000u,  1u}, // arz -> Arab
+    {0x61730000u,  7u}, // as -> Beng
+    {0x82400000u, 41u}, // asa -> Latn
+    {0x92400000u, 68u}, // ase -> Sgnw
+    {0xCE400000u, 41u}, // ast -> Latn
+    {0xA6600000u, 41u}, // atj -> Latn
+    {0x61760000u, 15u}, // av -> Cyrl
+    {0x82C00000u, 16u}, // awa -> Deva
+    {0x61790000u, 41u}, // ay -> Latn
+    {0x617A0000u, 41u}, // az -> Latn
+    {0x617A4951u,  1u}, // az-IQ -> Arab
+    {0x617A4952u,  1u}, // az-IR -> Arab
+    {0x617A5255u, 15u}, // az-RU -> Cyrl
+    {0x62610000u, 15u}, // ba -> Cyrl
+    {0xAC010000u,  1u}, // bal -> Arab
+    {0xB4010000u, 41u}, // ban -> Latn
+    {0xBC010000u, 16u}, // bap -> Deva
+    {0xC4010000u, 41u}, // bar -> Latn
+    {0xC8010000u, 41u}, // bas -> Latn
+    {0xDC010000u,  5u}, // bax -> Bamu
+    {0x88210000u, 41u}, // bbc -> Latn
+    {0xA4210000u, 41u}, // bbj -> Latn
+    {0xA0410000u, 41u}, // bci -> Latn
+    {0x62650000u, 15u}, // be -> Cyrl
+    {0xA4810000u,  1u}, // bej -> Arab
+    {0xB0810000u, 41u}, // bem -> Latn
+    {0xD8810000u, 41u}, // bew -> Latn
+    {0xE4810000u, 41u}, // bez -> Latn
+    {0x8CA10000u, 41u}, // bfd -> Latn
+    {0xC0A10000u, 74u}, // bfq -> Taml
+    {0xCCA10000u,  1u}, // bft -> Arab
+    {0xE0A10000u, 16u}, // bfy -> Deva
+    {0x62670000u, 15u}, // bg -> Cyrl
+    {0x88C10000u, 16u}, // bgc -> Deva
+    {0xB4C10000u,  1u}, // bgn -> Arab
+    {0xDCC10000u, 21u}, // bgx -> Grek
+    {0x62680000u, 38u}, // bh -> Kthi
+    {0x84E10000u, 16u}, // bhb -> Deva
+    {0xA0E10000u, 16u}, // bhi -> Deva
+    {0xA8E10000u, 41u}, // bhk -> Latn
+    {0xB8E10000u, 16u}, // bho -> Deva
+    {0x62690000u, 41u}, // bi -> Latn
+    {0xA9010000u, 41u}, // bik -> Latn
+    {0xB5010000u, 41u}, // bin -> Latn
+    {0xA5210000u, 16u}, // bjj -> Deva
+    {0xB5210000u, 41u}, // bjn -> Latn
+    {0xB1410000u, 41u}, // bkm -> Latn
+    {0xD1410000u, 41u}, // bku -> Latn
+    {0xCD610000u, 75u}, // blt -> Tavt
+    {0x626D0000u, 41u}, // bm -> Latn
+    {0xC1810000u, 41u}, // bmq -> Latn
+    {0x626E0000u,  7u}, // bn -> Beng
+    {0x626F0000u, 80u}, // bo -> Tibt
+    {0xE1E10000u,  7u}, // bpy -> Beng
+    {0xA2010000u,  1u}, // bqi -> Arab
+    {0xD6010000u, 41u}, // bqv -> Latn
+    {0x62720000u, 41u}, // br -> Latn
+    {0x82210000u, 16u}, // bra -> Deva
+    {0x9E210000u,  1u}, // brh -> Arab
+    {0xDE210000u, 16u}, // brx -> Deva
+    {0x62730000u, 41u}, // bs -> Latn
+    {0xC2410000u,  6u}, // bsq -> Bass
+    {0xCA410000u, 41u}, // bss -> Latn
+    {0xBA610000u, 41u}, // bto -> Latn
+    {0xD6610000u, 16u}, // btv -> Deva
+    {0x82810000u, 15u}, // bua -> Cyrl
+    {0x8A810000u, 41u}, // buc -> Latn
+    {0x9A810000u, 41u}, // bug -> Latn
+    {0xB2810000u, 41u}, // bum -> Latn
+    {0x86A10000u, 41u}, // bvb -> Latn
+    {0xB7010000u, 18u}, // byn -> Ethi
+    {0xD7010000u, 41u}, // byv -> Latn
+    {0x93210000u, 41u}, // bze -> Latn
+    {0x63610000u, 41u}, // ca -> Latn
+    {0x9C420000u, 41u}, // cch -> Latn
+    {0xBC420000u,  7u}, // ccp -> Beng
+    {0x63650000u, 15u}, // ce -> Cyrl
+    {0x84820000u, 41u}, // ceb -> Latn
+    {0x98C20000u, 41u}, // cgg -> Latn
+    {0x63680000u, 41u}, // ch -> Latn
+    {0xA8E20000u, 41u}, // chk -> Latn
+    {0xB0E20000u, 15u}, // chm -> Cyrl
+    {0xB8E20000u, 41u}, // cho -> Latn
+    {0xBCE20000u, 41u}, // chp -> Latn
+    {0xC4E20000u, 12u}, // chr -> Cher
+    {0x81220000u,  1u}, // cja -> Arab
+    {0xB1220000u, 11u}, // cjm -> Cham
+    {0x85420000u,  1u}, // ckb -> Arab
+    {0x636F0000u, 41u}, // co -> Latn
+    {0xBDC20000u, 13u}, // cop -> Copt
+    {0xC9E20000u, 41u}, // cps -> Latn
+    {0x63720000u,  9u}, // cr -> Cans
+    {0xA6220000u,  9u}, // crj -> Cans
+    {0xAA220000u,  9u}, // crk -> Cans
+    {0xAE220000u,  9u}, // crl -> Cans
+    {0xB2220000u,  9u}, // crm -> Cans
+    {0xCA220000u, 41u}, // crs -> Latn
+    {0x63730000u, 41u}, // cs -> Latn
+    {0x86420000u, 41u}, // csb -> Latn
+    {0xDA420000u,  9u}, // csw -> Cans
+    {0x8E620000u, 59u}, // ctd -> Pauc
+    {0x63750000u, 15u}, // cu -> Cyrl
+    {0x63760000u, 15u}, // cv -> Cyrl
+    {0x63790000u, 41u}, // cy -> Latn
+    {0x64610000u, 41u}, // da -> Latn
+    {0xA8030000u, 41u}, // dak -> Latn
+    {0xC4030000u, 15u}, // dar -> Cyrl
+    {0xD4030000u, 41u}, // dav -> Latn
+    {0x88430000u,  1u}, // dcc -> Arab
+    {0x64650000u, 41u}, // de -> Latn
+    {0xB4830000u, 41u}, // den -> Latn
+    {0xC4C30000u, 41u}, // dgr -> Latn
+    {0x91230000u, 41u}, // dje -> Latn
+    {0xA5A30000u, 41u}, // dnj -> Latn
+    {0xA1C30000u,  1u}, // doi -> Arab
+    {0x86430000u, 41u}, // dsb -> Latn
+    {0xB2630000u, 41u}, // dtm -> Latn
+    {0xBE630000u, 41u}, // dtp -> Latn
+    {0x82830000u, 41u}, // dua -> Latn
+    {0x64760000u, 78u}, // dv -> Thaa
+    {0xBB030000u, 41u}, // dyo -> Latn
+    {0xD3030000u, 41u}, // dyu -> Latn
+    {0x647A0000u, 80u}, // dz -> Tibt
+    {0xD0240000u, 41u}, // ebu -> Latn
+    {0x65650000u, 41u}, // ee -> Latn
+    {0xA0A40000u, 41u}, // efi -> Latn
+    {0xACC40000u, 41u}, // egl -> Latn
+    {0xE0C40000u, 17u}, // egy -> Egyp
+    {0xE1440000u, 32u}, // eky -> Kali
+    {0x656C0000u, 21u}, // el -> Grek
+    {0x656E0000u, 41u}, // en -> Latn
+    {0x656E5841u, 86u}, // en-XA -> ~~~A
+    {0x656F0000u, 41u}, // eo -> Latn
+    {0x65730000u, 41u}, // es -> Latn
+    {0xD2440000u, 41u}, // esu -> Latn
+    {0x65740000u, 41u}, // et -> Latn
+    {0xCE640000u, 30u}, // ett -> Ital
+    {0x65750000u, 41u}, // eu -> Latn
+    {0xBAC40000u, 41u}, // ewo -> Latn
+    {0xCEE40000u, 41u}, // ext -> Latn
+    {0x66610000u,  1u}, // fa -> Arab
+    {0xB4050000u, 41u}, // fan -> Latn
+    {0x66660000u, 41u}, // ff -> Latn
+    {0xB0A50000u, 41u}, // ffm -> Latn
+    {0x66690000u, 41u}, // fi -> Latn
+    {0x81050000u,  1u}, // fia -> Arab
+    {0xAD050000u, 41u}, // fil -> Latn
+    {0xCD050000u, 41u}, // fit -> Latn
+    {0x666A0000u, 41u}, // fj -> Latn
+    {0x666F0000u, 41u}, // fo -> Latn
+    {0xB5C50000u, 41u}, // fon -> Latn
+    {0x66720000u, 41u}, // fr -> Latn
+    {0x8A250000u, 41u}, // frc -> Latn
+    {0xBE250000u, 41u}, // frp -> Latn
+    {0xC6250000u, 41u}, // frr -> Latn
+    {0xCA250000u, 41u}, // frs -> Latn
+    {0x8E850000u, 41u}, // fud -> Latn
+    {0xC2850000u, 41u}, // fuq -> Latn
+    {0xC6850000u, 41u}, // fur -> Latn
+    {0xD6850000u, 41u}, // fuv -> Latn
+    {0xC6A50000u, 41u}, // fvr -> Latn
+    {0x66790000u, 41u}, // fy -> Latn
+    {0x67610000u, 41u}, // ga -> Latn
+    {0x80060000u, 41u}, // gaa -> Latn
+    {0x98060000u, 41u}, // gag -> Latn
+    {0xB4060000u, 24u}, // gan -> Hans
+    {0xE0060000u, 41u}, // gay -> Latn
+    {0xB0260000u, 16u}, // gbm -> Deva
+    {0xE4260000u,  1u}, // gbz -> Arab
+    {0xC4460000u, 41u}, // gcr -> Latn
+    {0x67640000u, 41u}, // gd -> Latn
+    {0xE4860000u, 18u}, // gez -> Ethi
+    {0xB4C60000u, 16u}, // ggn -> Deva
+    {0xAD060000u, 41u}, // gil -> Latn
+    {0xA9260000u,  1u}, // gjk -> Arab
+    {0xD1260000u,  1u}, // gju -> Arab
+    {0x676C0000u, 41u}, // gl -> Latn
+    {0xA9660000u,  1u}, // glk -> Arab
+    {0x676E0000u, 41u}, // gn -> Latn
+    {0xB1C60000u, 16u}, // gom -> Deva
+    {0xB5C60000u, 76u}, // gon -> Telu
+    {0xC5C60000u, 41u}, // gor -> Latn
+    {0xC9C60000u, 41u}, // gos -> Latn
+    {0xCDC60000u, 20u}, // got -> Goth
+    {0x8A260000u, 14u}, // grc -> Cprt
+    {0xCE260000u,  7u}, // grt -> Beng
+    {0xDA460000u, 41u}, // gsw -> Latn
+    {0x67750000u, 22u}, // gu -> Gujr
+    {0x86860000u, 41u}, // gub -> Latn
+    {0x8A860000u, 41u}, // guc -> Latn
+    {0xC6860000u, 41u}, // gur -> Latn
+    {0xE6860000u, 41u}, // guz -> Latn
+    {0x67760000u, 41u}, // gv -> Latn
+    {0xC6A60000u, 16u}, // gvr -> Deva
+    {0xA2C60000u, 41u}, // gwi -> Latn
+    {0x68610000u, 41u}, // ha -> Latn
+    {0x6861434Du,  1u}, // ha-CM -> Arab
+    {0x68615344u,  1u}, // ha-SD -> Arab
+    {0xA8070000u, 24u}, // hak -> Hans
+    {0xD8070000u, 41u}, // haw -> Latn
+    {0xE4070000u,  1u}, // haz -> Arab
+    {0x68650000u, 27u}, // he -> Hebr
+    {0x68690000u, 16u}, // hi -> Deva
+    {0x95070000u, 41u}, // hif -> Latn
+    {0xAD070000u, 41u}, // hil -> Latn
+    {0xD1670000u, 28u}, // hlu -> Hluw
+    {0x8D870000u, 62u}, // hmd -> Plrd
+    {0x8DA70000u,  1u}, // hnd -> Arab
+    {0x91A70000u, 16u}, // hne -> Deva
+    {0xA5A70000u, 29u}, // hnj -> Hmng
+    {0xB5A70000u, 41u}, // hnn -> Latn
+    {0xB9A70000u,  1u}, // hno -> Arab
+    {0x686F0000u, 41u}, // ho -> Latn
+    {0x89C70000u, 16u}, // hoc -> Deva
+    {0xA5C70000u, 16u}, // hoj -> Deva
+    {0x68720000u, 41u}, // hr -> Latn
+    {0x86470000u, 41u}, // hsb -> Latn
+    {0xB6470000u, 24u}, // hsn -> Hans
+    {0x68740000u, 41u}, // ht -> Latn
+    {0x68750000u, 41u}, // hu -> Latn
+    {0x68790000u,  3u}, // hy -> Armn
+    {0x687A0000u, 41u}, // hz -> Latn
+    {0x69610000u, 41u}, // ia -> Latn
+    {0x80280000u, 41u}, // iba -> Latn
+    {0x84280000u, 41u}, // ibb -> Latn
+    {0x69640000u, 41u}, // id -> Latn
+    {0x69670000u, 41u}, // ig -> Latn
+    {0x69690000u, 85u}, // ii -> Yiii
+    {0x696B0000u, 41u}, // ik -> Latn
+    {0xCD480000u, 41u}, // ikt -> Latn
+    {0xB9680000u, 41u}, // ilo -> Latn
+    {0x696E0000u, 41u}, // in -> Latn
+    {0x9DA80000u, 15u}, // inh -> Cyrl
+    {0x69730000u, 41u}, // is -> Latn
+    {0x69740000u, 41u}, // it -> Latn
+    {0x69750000u,  9u}, // iu -> Cans
+    {0x69770000u, 27u}, // iw -> Hebr
+    {0x9F280000u, 41u}, // izh -> Latn
+    {0x6A610000u, 31u}, // ja -> Jpan
+    {0xB0090000u, 41u}, // jam -> Latn
+    {0xB8C90000u, 41u}, // jgo -> Latn
+    {0x6A690000u, 27u}, // ji -> Hebr
+    {0x89890000u, 41u}, // jmc -> Latn
+    {0xAD890000u, 16u}, // jml -> Deva
+    {0xCE890000u, 41u}, // jut -> Latn
+    {0x6A760000u, 41u}, // jv -> Latn
+    {0x6A770000u, 41u}, // jw -> Latn
+    {0x6B610000u, 19u}, // ka -> Geor
+    {0x800A0000u, 15u}, // kaa -> Cyrl
+    {0x840A0000u, 41u}, // kab -> Latn
+    {0x880A0000u, 41u}, // kac -> Latn
+    {0xA40A0000u, 41u}, // kaj -> Latn
+    {0xB00A0000u, 41u}, // kam -> Latn
+    {0xB80A0000u, 41u}, // kao -> Latn
+    {0x8C2A0000u, 15u}, // kbd -> Cyrl
+    {0x984A0000u, 41u}, // kcg -> Latn
+    {0xA84A0000u, 41u}, // kck -> Latn
+    {0x906A0000u, 41u}, // kde -> Latn
+    {0xCC6A0000u, 79u}, // kdt -> Thai
+    {0x808A0000u, 41u}, // kea -> Latn
+    {0xB48A0000u, 41u}, // ken -> Latn
+    {0xB8AA0000u, 41u}, // kfo -> Latn
+    {0xC4AA0000u, 16u}, // kfr -> Deva
+    {0xE0AA0000u, 16u}, // kfy -> Deva
+    {0x6B670000u, 41u}, // kg -> Latn
+    {0x90CA0000u, 41u}, // kge -> Latn
+    {0xBCCA0000u, 41u}, // kgp -> Latn
+    {0x80EA0000u, 41u}, // kha -> Latn
+    {0x84EA0000u, 73u}, // khb -> Talu
+    {0xB4EA0000u, 16u}, // khn -> Deva
+    {0xC0EA0000u, 41u}, // khq -> Latn
+    {0xCCEA0000u, 53u}, // kht -> Mymr
+    {0xD8EA0000u,  1u}, // khw -> Arab
+    {0x6B690000u, 41u}, // ki -> Latn
+    {0xD10A0000u, 41u}, // kiu -> Latn
+    {0x6B6A0000u, 41u}, // kj -> Latn
+    {0x992A0000u, 40u}, // kjg -> Laoo
+    {0x6B6B0000u, 15u}, // kk -> Cyrl
+    {0x6B6B4146u,  1u}, // kk-AF -> Arab
+    {0x6B6B434Eu,  1u}, // kk-CN -> Arab
+    {0x6B6B4952u,  1u}, // kk-IR -> Arab
+    {0x6B6B4D4Eu,  1u}, // kk-MN -> Arab
+    {0xA54A0000u, 41u}, // kkj -> Latn
+    {0x6B6C0000u, 41u}, // kl -> Latn
+    {0xB56A0000u, 41u}, // kln -> Latn
+    {0x6B6D0000u, 35u}, // km -> Khmr
+    {0x858A0000u, 41u}, // kmb -> Latn
+    {0x6B6E0000u, 36u}, // kn -> Knda
+    {0x6B6F0000u, 37u}, // ko -> Kore
+    {0xA1CA0000u, 15u}, // koi -> Cyrl
+    {0xA9CA0000u, 16u}, // kok -> Deva
+    {0xC9CA0000u, 41u}, // kos -> Latn
+    {0x91EA0000u, 41u}, // kpe -> Latn
+    {0x8A2A0000u, 15u}, // krc -> Cyrl
+    {0xA22A0000u, 41u}, // kri -> Latn
+    {0xA62A0000u, 41u}, // krj -> Latn
+    {0xAE2A0000u, 41u}, // krl -> Latn
+    {0xD22A0000u, 16u}, // kru -> Deva
+    {0x6B730000u,  1u}, // ks -> Arab
+    {0x864A0000u, 41u}, // ksb -> Latn
+    {0x964A0000u, 41u}, // ksf -> Latn
+    {0x9E4A0000u, 41u}, // ksh -> Latn
+    {0x6B750000u, 41u}, // ku -> Latn
+    {0x6B754952u,  1u}, // ku-IR -> Arab
+    {0x6B754C42u,  1u}, // ku-LB -> Arab
+    {0xB28A0000u, 15u}, // kum -> Cyrl
+    {0x6B760000u, 15u}, // kv -> Cyrl
+    {0xC6AA0000u, 41u}, // kvr -> Latn
+    {0xDEAA0000u,  1u}, // kvx -> Arab
+    {0x6B770000u, 41u}, // kw -> Latn
+    {0xB2EA0000u, 79u}, // kxm -> Thai
+    {0xBEEA0000u,  1u}, // kxp -> Arab
+    {0x6B790000u, 15u}, // ky -> Cyrl
+    {0x6B79434Eu,  1u}, // ky-CN -> Arab
+    {0x6B795452u, 41u}, // ky-TR -> Latn
+    {0x6C610000u, 41u}, // la -> Latn
+    {0x840B0000u, 43u}, // lab -> Lina
+    {0x8C0B0000u, 27u}, // lad -> Hebr
+    {0x980B0000u, 41u}, // lag -> Latn
+    {0x9C0B0000u,  1u}, // lah -> Arab
+    {0xA40B0000u, 41u}, // laj -> Latn
+    {0x6C620000u, 41u}, // lb -> Latn
+    {0x902B0000u, 15u}, // lbe -> Cyrl
+    {0xD82B0000u, 41u}, // lbw -> Latn
+    {0xBC4B0000u, 79u}, // lcp -> Thai
+    {0xBC8B0000u, 42u}, // lep -> Lepc
+    {0xE48B0000u, 15u}, // lez -> Cyrl
+    {0x6C670000u, 41u}, // lg -> Latn
+    {0x6C690000u, 41u}, // li -> Latn
+    {0x950B0000u, 16u}, // lif -> Deva
+    {0xA50B0000u, 41u}, // lij -> Latn
+    {0xC90B0000u, 44u}, // lis -> Lisu
+    {0xBD2B0000u, 41u}, // ljp -> Latn
+    {0xA14B0000u,  1u}, // lki -> Arab
+    {0xCD4B0000u, 41u}, // lkt -> Latn
+    {0xB58B0000u, 76u}, // lmn -> Telu
+    {0xB98B0000u, 41u}, // lmo -> Latn
+    {0x6C6E0000u, 41u}, // ln -> Latn
+    {0x6C6F0000u, 40u}, // lo -> Laoo
+    {0xADCB0000u, 41u}, // lol -> Latn
+    {0xE5CB0000u, 41u}, // loz -> Latn
+    {0x8A2B0000u,  1u}, // lrc -> Arab
+    {0x6C740000u, 41u}, // lt -> Latn
+    {0x9A6B0000u, 41u}, // ltg -> Latn
+    {0x6C750000u, 41u}, // lu -> Latn
+    {0x828B0000u, 41u}, // lua -> Latn
+    {0xBA8B0000u, 41u}, // luo -> Latn
+    {0xE28B0000u, 41u}, // luy -> Latn
+    {0xE68B0000u,  1u}, // luz -> Arab
+    {0x6C760000u, 41u}, // lv -> Latn
+    {0xAECB0000u, 79u}, // lwl -> Thai
+    {0x9F2B0000u, 24u}, // lzh -> Hans
+    {0xE72B0000u, 41u}, // lzz -> Latn
+    {0x8C0C0000u, 41u}, // mad -> Latn
+    {0x940C0000u, 41u}, // maf -> Latn
+    {0x980C0000u, 16u}, // mag -> Deva
+    {0xA00C0000u, 16u}, // mai -> Deva
+    {0xA80C0000u, 41u}, // mak -> Latn
+    {0xB40C0000u, 41u}, // man -> Latn
+    {0xB40C474Eu, 55u}, // man-GN -> Nkoo
+    {0xC80C0000u, 41u}, // mas -> Latn
+    {0xE40C0000u, 41u}, // maz -> Latn
+    {0x946C0000u, 15u}, // mdf -> Cyrl
+    {0x9C6C0000u, 41u}, // mdh -> Latn
+    {0xC46C0000u, 41u}, // mdr -> Latn
+    {0xB48C0000u, 41u}, // men -> Latn
+    {0xC48C0000u, 41u}, // mer -> Latn
+    {0x80AC0000u,  1u}, // mfa -> Arab
+    {0x90AC0000u, 41u}, // mfe -> Latn
+    {0x6D670000u, 41u}, // mg -> Latn
+    {0x9CCC0000u, 41u}, // mgh -> Latn
+    {0xB8CC0000u, 41u}, // mgo -> Latn
+    {0xBCCC0000u, 16u}, // mgp -> Deva
+    {0xE0CC0000u, 41u}, // mgy -> Latn
+    {0x6D680000u, 41u}, // mh -> Latn
+    {0x6D690000u, 41u}, // mi -> Latn
+    {0xB50C0000u, 41u}, // min -> Latn
+    {0xC90C0000u, 26u}, // mis -> Hatr
+    {0x6D6B0000u, 15u}, // mk -> Cyrl
+    {0x6D6C0000u, 50u}, // ml -> Mlym
+    {0xC96C0000u, 41u}, // mls -> Latn
+    {0x6D6E0000u, 15u}, // mn -> Cyrl
+    {0x6D6E434Eu, 51u}, // mn-CN -> Mong
+    {0xA1AC0000u,  7u}, // mni -> Beng
+    {0xD9AC0000u, 53u}, // mnw -> Mymr
+    {0x91CC0000u, 41u}, // moe -> Latn
+    {0x9DCC0000u, 41u}, // moh -> Latn
+    {0xC9CC0000u, 41u}, // mos -> Latn
+    {0x6D720000u, 16u}, // mr -> Deva
+    {0x8E2C0000u, 16u}, // mrd -> Deva
+    {0xA62C0000u, 15u}, // mrj -> Cyrl
+    {0xD22C0000u, 52u}, // mru -> Mroo
+    {0x6D730000u, 41u}, // ms -> Latn
+    {0x6D734343u,  1u}, // ms-CC -> Arab
+    {0x6D734944u,  1u}, // ms-ID -> Arab
+    {0x6D740000u, 41u}, // mt -> Latn
+    {0xC66C0000u, 16u}, // mtr -> Deva
+    {0x828C0000u, 41u}, // mua -> Latn
+    {0xCA8C0000u, 41u}, // mus -> Latn
+    {0xE2AC0000u,  1u}, // mvy -> Arab
+    {0xAACC0000u, 41u}, // mwk -> Latn
+    {0xC6CC0000u, 16u}, // mwr -> Deva
+    {0xD6CC0000u, 41u}, // mwv -> Latn
+    {0x8AEC0000u, 41u}, // mxc -> Latn
+    {0x6D790000u, 53u}, // my -> Mymr
+    {0xD70C0000u, 15u}, // myv -> Cyrl
+    {0xDF0C0000u, 41u}, // myx -> Latn
+    {0xE70C0000u, 47u}, // myz -> Mand
+    {0xB72C0000u,  1u}, // mzn -> Arab
+    {0x6E610000u, 41u}, // na -> Latn
+    {0xB40D0000u, 24u}, // nan -> Hans
+    {0xBC0D0000u, 41u}, // nap -> Latn
+    {0xC00D0000u, 41u}, // naq -> Latn
+    {0x6E620000u, 41u}, // nb -> Latn
+    {0x9C4D0000u, 41u}, // nch -> Latn
+    {0x6E640000u, 41u}, // nd -> Latn
+    {0x886D0000u, 41u}, // ndc -> Latn
+    {0xC86D0000u, 41u}, // nds -> Latn
+    {0x6E650000u, 16u}, // ne -> Deva
+    {0xD88D0000u, 16u}, // new -> Deva
+    {0x6E670000u, 41u}, // ng -> Latn
+    {0xACCD0000u, 41u}, // ngl -> Latn
+    {0x90ED0000u, 41u}, // nhe -> Latn
+    {0xD8ED0000u, 41u}, // nhw -> Latn
+    {0xA50D0000u, 41u}, // nij -> Latn
+    {0xD10D0000u, 41u}, // niu -> Latn
+    {0xB92D0000u, 41u}, // njo -> Latn
+    {0x6E6C0000u, 41u}, // nl -> Latn
+    {0x998D0000u, 41u}, // nmg -> Latn
+    {0x6E6E0000u, 41u}, // nn -> Latn
+    {0x9DAD0000u, 41u}, // nnh -> Latn
+    {0x6E6F0000u, 41u}, // no -> Latn
+    {0x8DCD0000u, 39u}, // nod -> Lana
+    {0x91CD0000u, 16u}, // noe -> Deva
+    {0xB5CD0000u, 64u}, // non -> Runr
+    {0xBA0D0000u, 55u}, // nqo -> Nkoo
+    {0x6E720000u, 41u}, // nr -> Latn
+    {0xAA4D0000u,  9u}, // nsk -> Cans
+    {0xBA4D0000u, 41u}, // nso -> Latn
+    {0xCA8D0000u, 41u}, // nus -> Latn
+    {0x6E760000u, 41u}, // nv -> Latn
+    {0xC2ED0000u, 41u}, // nxq -> Latn
+    {0x6E790000u, 41u}, // ny -> Latn
+    {0xB30D0000u, 41u}, // nym -> Latn
+    {0xB70D0000u, 41u}, // nyn -> Latn
+    {0xA32D0000u, 41u}, // nzi -> Latn
+    {0x6F630000u, 41u}, // oc -> Latn
+    {0x6F6D0000u, 41u}, // om -> Latn
+    {0x6F720000u, 58u}, // or -> Orya
+    {0x6F730000u, 15u}, // os -> Cyrl
+    {0xAA6E0000u, 57u}, // otk -> Orkh
+    {0x70610000u, 23u}, // pa -> Guru
+    {0x7061504Bu,  1u}, // pa-PK -> Arab
+    {0x980F0000u, 41u}, // pag -> Latn
+    {0xAC0F0000u, 60u}, // pal -> Phli
+    {0xB00F0000u, 41u}, // pam -> Latn
+    {0xBC0F0000u, 41u}, // pap -> Latn
+    {0xD00F0000u, 41u}, // pau -> Latn
+    {0x8C4F0000u, 41u}, // pcd -> Latn
+    {0xB04F0000u, 41u}, // pcm -> Latn
+    {0x886F0000u, 41u}, // pdc -> Latn
+    {0xCC6F0000u, 41u}, // pdt -> Latn
+    {0xB88F0000u, 83u}, // peo -> Xpeo
+    {0xACAF0000u, 41u}, // pfl -> Latn
+    {0xB4EF0000u, 61u}, // phn -> Phnx
+    {0x814F0000u,  8u}, // pka -> Brah
+    {0xB94F0000u, 41u}, // pko -> Latn
+    {0x706C0000u, 41u}, // pl -> Latn
+    {0xC98F0000u, 41u}, // pms -> Latn
+    {0xCDAF0000u, 21u}, // pnt -> Grek
+    {0xB5CF0000u, 41u}, // pon -> Latn
+    {0x822F0000u, 34u}, // pra -> Khar
+    {0x8E2F0000u,  1u}, // prd -> Arab
+    {0x9A2F0000u, 41u}, // prg -> Latn
+    {0x70730000u,  1u}, // ps -> Arab
+    {0x70740000u, 41u}, // pt -> Latn
+    {0xD28F0000u, 41u}, // puu -> Latn
+    {0x71750000u, 41u}, // qu -> Latn
+    {0x8A900000u, 41u}, // quc -> Latn
+    {0x9A900000u, 41u}, // qug -> Latn
+    {0xA4110000u, 16u}, // raj -> Deva
+    {0x94510000u, 41u}, // rcf -> Latn
+    {0xA4910000u, 41u}, // rej -> Latn
+    {0xB4D10000u, 41u}, // rgn -> Latn
+    {0x81110000u, 41u}, // ria -> Latn
+    {0x95110000u, 77u}, // rif -> Tfng
+    {0x95114E4Cu, 41u}, // rif-NL -> Latn
+    {0xC9310000u, 16u}, // rjs -> Deva
+    {0xCD510000u,  7u}, // rkt -> Beng
+    {0x726D0000u, 41u}, // rm -> Latn
+    {0x95910000u, 41u}, // rmf -> Latn
+    {0xB9910000u, 41u}, // rmo -> Latn
+    {0xCD910000u,  1u}, // rmt -> Arab
+    {0xD1910000u, 41u}, // rmu -> Latn
+    {0x726E0000u, 41u}, // rn -> Latn
+    {0x99B10000u, 41u}, // rng -> Latn
+    {0x726F0000u, 41u}, // ro -> Latn
+    {0x85D10000u, 41u}, // rob -> Latn
+    {0x95D10000u, 41u}, // rof -> Latn
+    {0xB2710000u, 41u}, // rtm -> Latn
+    {0x72750000u, 15u}, // ru -> Cyrl
+    {0x92910000u, 15u}, // rue -> Cyrl
+    {0x9A910000u, 41u}, // rug -> Latn
+    {0x72770000u, 41u}, // rw -> Latn
+    {0xAAD10000u, 41u}, // rwk -> Latn
+    {0xD3110000u, 33u}, // ryu -> Kana
+    {0x73610000u, 16u}, // sa -> Deva
+    {0x94120000u, 41u}, // saf -> Latn
+    {0x9C120000u, 15u}, // sah -> Cyrl
+    {0xC0120000u, 41u}, // saq -> Latn
+    {0xC8120000u, 41u}, // sas -> Latn
+    {0xCC120000u, 41u}, // sat -> Latn
+    {0xE4120000u, 67u}, // saz -> Saur
+    {0xBC320000u, 41u}, // sbp -> Latn
+    {0x73630000u, 41u}, // sc -> Latn
+    {0xA8520000u, 16u}, // sck -> Deva
+    {0xB4520000u, 41u}, // scn -> Latn
+    {0xB8520000u, 41u}, // sco -> Latn
+    {0xC8520000u, 41u}, // scs -> Latn
+    {0x73640000u,  1u}, // sd -> Arab
+    {0x88720000u, 41u}, // sdc -> Latn
+    {0x9C720000u,  1u}, // sdh -> Arab
+    {0x73650000u, 41u}, // se -> Latn
+    {0x94920000u, 41u}, // sef -> Latn
+    {0x9C920000u, 41u}, // seh -> Latn
+    {0xA0920000u, 41u}, // sei -> Latn
+    {0xC8920000u, 41u}, // ses -> Latn
+    {0x73670000u, 41u}, // sg -> Latn
+    {0x80D20000u, 56u}, // sga -> Ogam
+    {0xC8D20000u, 41u}, // sgs -> Latn
+    {0x73680000u, 41u}, // sh -> Latn
+    {0xA0F20000u, 77u}, // shi -> Tfng
+    {0xB4F20000u, 53u}, // shn -> Mymr
+    {0x73690000u, 69u}, // si -> Sinh
+    {0x8D120000u, 41u}, // sid -> Latn
+    {0x736B0000u, 41u}, // sk -> Latn
+    {0xC5520000u,  1u}, // skr -> Arab
+    {0x736C0000u, 41u}, // sl -> Latn
+    {0xA1720000u, 41u}, // sli -> Latn
+    {0xE1720000u, 41u}, // sly -> Latn
+    {0x736D0000u, 41u}, // sm -> Latn
+    {0x81920000u, 41u}, // sma -> Latn
+    {0xA5920000u, 41u}, // smj -> Latn
+    {0xB5920000u, 41u}, // smn -> Latn
+    {0xBD920000u, 65u}, // smp -> Samr
+    {0xC9920000u, 41u}, // sms -> Latn
+    {0x736E0000u, 41u}, // sn -> Latn
+    {0xA9B20000u, 41u}, // snk -> Latn
+    {0x736F0000u, 41u}, // so -> Latn
+    {0xD1D20000u, 79u}, // sou -> Thai
+    {0x73710000u, 41u}, // sq -> Latn
+    {0x73720000u, 15u}, // sr -> Cyrl
+    {0x73724D45u, 41u}, // sr-ME -> Latn
+    {0x7372524Fu, 41u}, // sr-RO -> Latn
+    {0x73725255u, 41u}, // sr-RU -> Latn
+    {0x73725452u, 41u}, // sr-TR -> Latn
+    {0x86320000u, 70u}, // srb -> Sora
+    {0xB6320000u, 41u}, // srn -> Latn
+    {0xC6320000u, 41u}, // srr -> Latn
+    {0xDE320000u, 16u}, // srx -> Deva
+    {0x73730000u, 41u}, // ss -> Latn
+    {0xE2520000u, 41u}, // ssy -> Latn
+    {0x73740000u, 41u}, // st -> Latn
+    {0xC2720000u, 41u}, // stq -> Latn
+    {0x73750000u, 41u}, // su -> Latn
+    {0xAA920000u, 41u}, // suk -> Latn
+    {0xCA920000u, 41u}, // sus -> Latn
+    {0x73760000u, 41u}, // sv -> Latn
+    {0x73770000u, 41u}, // sw -> Latn
+    {0x86D20000u,  1u}, // swb -> Arab
+    {0x8AD20000u, 41u}, // swc -> Latn
+    {0x9AD20000u, 41u}, // swg -> Latn
+    {0xD6D20000u, 16u}, // swv -> Deva
+    {0xB6F20000u, 41u}, // sxn -> Latn
+    {0xAF120000u,  7u}, // syl -> Beng
+    {0xC7120000u, 71u}, // syr -> Syrc
+    {0xAF320000u, 41u}, // szl -> Latn
+    {0x74610000u, 74u}, // ta -> Taml
+    {0xA4130000u, 16u}, // taj -> Deva
+    {0xD8330000u, 41u}, // tbw -> Latn
+    {0xE0530000u, 36u}, // tcy -> Knda
+    {0x8C730000u, 72u}, // tdd -> Tale
+    {0x98730000u, 16u}, // tdg -> Deva
+    {0x9C730000u, 16u}, // tdh -> Deva
+    {0x74650000u, 76u}, // te -> Telu
+    {0xB0930000u, 41u}, // tem -> Latn
+    {0xB8930000u, 41u}, // teo -> Latn
+    {0xCC930000u, 41u}, // tet -> Latn
+    {0x74670000u, 15u}, // tg -> Cyrl
+    {0x7467504Bu,  1u}, // tg-PK -> Arab
+    {0x74680000u, 79u}, // th -> Thai
+    {0xACF30000u, 16u}, // thl -> Deva
+    {0xC0F30000u, 16u}, // thq -> Deva
+    {0xC4F30000u, 16u}, // thr -> Deva
+    {0x74690000u, 18u}, // ti -> Ethi
+    {0x99130000u, 18u}, // tig -> Ethi
+    {0xD5130000u, 41u}, // tiv -> Latn
+    {0x746B0000u, 41u}, // tk -> Latn
+    {0xAD530000u, 41u}, // tkl -> Latn
+    {0xC5530000u, 41u}, // tkr -> Latn
+    {0xCD530000u, 16u}, // tkt -> Deva
+    {0x746C0000u, 41u}, // tl -> Latn
+    {0xE1730000u, 41u}, // tly -> Latn
+    {0x9D930000u, 41u}, // tmh -> Latn
+    {0x746E0000u, 41u}, // tn -> Latn
+    {0x746F0000u, 41u}, // to -> Latn
+    {0x99D30000u, 41u}, // tog -> Latn
+    {0xA1F30000u, 41u}, // tpi -> Latn
+    {0x74720000u, 41u}, // tr -> Latn
+    {0xD2330000u, 41u}, // tru -> Latn
+    {0xD6330000u, 41u}, // trv -> Latn
+    {0x74730000u, 41u}, // ts -> Latn
+    {0x8E530000u, 21u}, // tsd -> Grek
+    {0x96530000u, 16u}, // tsf -> Deva
+    {0x9A530000u, 41u}, // tsg -> Latn
+    {0xA6530000u, 80u}, // tsj -> Tibt
+    {0x74740000u, 15u}, // tt -> Cyrl
+    {0xA6730000u, 41u}, // ttj -> Latn
+    {0xCA730000u, 79u}, // tts -> Thai
+    {0xCE730000u, 41u}, // ttt -> Latn
+    {0xB2930000u, 41u}, // tum -> Latn
+    {0xAEB30000u, 41u}, // tvl -> Latn
+    {0xC2D30000u, 41u}, // twq -> Latn
+    {0x74790000u, 41u}, // ty -> Latn
+    {0xD7130000u, 15u}, // tyv -> Cyrl
+    {0xB3330000u, 41u}, // tzm -> Latn
+    {0xB0740000u, 15u}, // udm -> Cyrl
+    {0x75670000u,  1u}, // ug -> Arab
+    {0x75674B5Au, 15u}, // ug-KZ -> Cyrl
+    {0x75674D4Eu, 15u}, // ug-MN -> Cyrl
+    {0x80D40000u, 81u}, // uga -> Ugar
+    {0x756B0000u, 15u}, // uk -> Cyrl
+    {0xA1740000u, 41u}, // uli -> Latn
+    {0x85940000u, 41u}, // umb -> Latn
+    {0xC5B40000u,  7u}, // unr -> Beng
+    {0xC5B44E50u, 16u}, // unr-NP -> Deva
+    {0xDDB40000u,  7u}, // unx -> Beng
+    {0x75720000u,  1u}, // ur -> Arab
+    {0x757A0000u, 41u}, // uz -> Latn
+    {0x757A4146u,  1u}, // uz-AF -> Arab
+    {0x757A434Eu, 15u}, // uz-CN -> Cyrl
+    {0xA0150000u, 82u}, // vai -> Vaii
+    {0x76650000u, 41u}, // ve -> Latn
+    {0x88950000u, 41u}, // vec -> Latn
+    {0xBC950000u, 41u}, // vep -> Latn
+    {0x76690000u, 41u}, // vi -> Latn
+    {0x89150000u, 41u}, // vic -> Latn
+    {0xC9750000u, 41u}, // vls -> Latn
+    {0x95950000u, 41u}, // vmf -> Latn
+    {0xD9950000u, 41u}, // vmw -> Latn
+    {0x766F0000u, 41u}, // vo -> Latn
+    {0xCDD50000u, 41u}, // vot -> Latn
+    {0xBA350000u, 41u}, // vro -> Latn
+    {0xB6950000u, 41u}, // vun -> Latn
+    {0x77610000u, 41u}, // wa -> Latn
+    {0x90160000u, 41u}, // wae -> Latn
+    {0xAC160000u, 18u}, // wal -> Ethi
+    {0xC4160000u, 41u}, // war -> Latn
+    {0xBC360000u, 41u}, // wbp -> Latn
+    {0xC0360000u, 76u}, // wbq -> Telu
+    {0xC4360000u, 16u}, // wbr -> Deva
+    {0xC9760000u, 41u}, // wls -> Latn
+    {0xA1B60000u,  1u}, // wni -> Arab
+    {0x776F0000u, 41u}, // wo -> Latn
+    {0xB2760000u, 16u}, // wtm -> Deva
+    {0xD2960000u, 24u}, // wuu -> Hans
+    {0xD4170000u, 41u}, // xav -> Latn
+    {0xC4570000u, 10u}, // xcr -> Cari
+    {0x78680000u, 41u}, // xh -> Latn
+    {0x89770000u, 45u}, // xlc -> Lyci
+    {0x8D770000u, 46u}, // xld -> Lydi
+    {0x95970000u, 19u}, // xmf -> Geor
+    {0xB5970000u, 48u}, // xmn -> Mani
+    {0xC5970000u, 49u}, // xmr -> Merc
+    {0x81B70000u, 54u}, // xna -> Narb
+    {0xC5B70000u, 16u}, // xnr -> Deva
+    {0x99D70000u, 41u}, // xog -> Latn
+    {0xC5F70000u, 63u}, // xpr -> Prti
+    {0x82570000u, 66u}, // xsa -> Sarb
+    {0xC6570000u, 16u}, // xsr -> Deva
+    {0xB8180000u, 41u}, // yao -> Latn
+    {0xBC180000u, 41u}, // yap -> Latn
+    {0xD4180000u, 41u}, // yav -> Latn
+    {0x84380000u, 41u}, // ybb -> Latn
+    {0x79690000u, 27u}, // yi -> Hebr
+    {0x796F0000u, 41u}, // yo -> Latn
+    {0xAE380000u, 41u}, // yrl -> Latn
+    {0x82980000u, 41u}, // yua -> Latn
+    {0x7A610000u, 41u}, // za -> Latn
+    {0x98190000u, 41u}, // zag -> Latn
+    {0xA4790000u,  1u}, // zdj -> Arab
+    {0x80990000u, 41u}, // zea -> Latn
+    {0x9CD90000u, 77u}, // zgh -> Tfng
+    {0x7A680000u, 24u}, // zh -> Hans
+    {0x7A684155u, 25u}, // zh-AU -> Hant
+    {0x7A68424Eu, 25u}, // zh-BN -> Hant
+    {0x7A684742u, 25u}, // zh-GB -> Hant
+    {0x7A684746u, 25u}, // zh-GF -> Hant
+    {0x7A68484Bu, 25u}, // zh-HK -> Hant
+    {0x7A684944u, 25u}, // zh-ID -> Hant
+    {0x7A684D4Fu, 25u}, // zh-MO -> Hant
+    {0x7A684D59u, 25u}, // zh-MY -> Hant
+    {0x7A685041u, 25u}, // zh-PA -> Hant
+    {0x7A685046u, 25u}, // zh-PF -> Hant
+    {0x7A685048u, 25u}, // zh-PH -> Hant
+    {0x7A685352u, 25u}, // zh-SR -> Hant
+    {0x7A685448u, 25u}, // zh-TH -> Hant
+    {0x7A685457u, 25u}, // zh-TW -> Hant
+    {0x7A685553u, 25u}, // zh-US -> Hant
+    {0x7A68564Eu, 25u}, // zh-VN -> Hant
+    {0xA1990000u, 41u}, // zmi -> Latn
+    {0x7A750000u, 41u}, // zu -> Latn
+    {0x83390000u, 41u}, // zza -> Latn
+});
+
+std::unordered_set<uint64_t> REPRESENTATIVE_LOCALES({
+    0x616145544C61746Ellu, // aa_Latn_ET
+    0x616247454379726Cllu, // ab_Cyrl_GE
+    0xC42047484C61746Ellu, // abr_Latn_GH
+    0x904049444C61746Ellu, // ace_Latn_ID
+    0x9C4055474C61746Ellu, // ach_Latn_UG
+    0x806047484C61746Ellu, // ada_Latn_GH
+    0xE06052554379726Cllu, // ady_Cyrl_RU
+    0x6165495241767374llu, // ae_Avst_IR
+    0x8480544E41726162llu, // aeb_Arab_TN
+    0x61665A414C61746Ellu, // af_Latn_ZA
+    0xC0C0434D4C61746Ellu, // agq_Latn_CM
+    0xB8E0494E41686F6Dllu, // aho_Ahom_IN
+    0x616B47484C61746Ellu, // ak_Latn_GH
+    0xA940495158737578llu, // akk_Xsux_IQ
+    0xB560584B4C61746Ellu, // aln_Latn_XK
+    0xCD6052554379726Cllu, // alt_Cyrl_RU
+    0x616D455445746869llu, // am_Ethi_ET
+    0xB9804E474C61746Ellu, // amo_Latn_NG
+    0xE5C049444C61746Ellu, // aoz_Latn_ID
+    0x6172454741726162llu, // ar_Arab_EG
+    0x8A20495241726D69llu, // arc_Armi_IR
+    0x8A204A4F4E626174llu, // arc_Nbat_JO
+    0x8A20535950616C6Dllu, // arc_Palm_SY
+    0xB620434C4C61746Ellu, // arn_Latn_CL
+    0xBA20424F4C61746Ellu, // aro_Latn_BO
+    0xC220445A41726162llu, // arq_Arab_DZ
+    0xE2204D4141726162llu, // ary_Arab_MA
+    0xE620454741726162llu, // arz_Arab_EG
+    0x6173494E42656E67llu, // as_Beng_IN
+    0x8240545A4C61746Ellu, // asa_Latn_TZ
+    0x9240555353676E77llu, // ase_Sgnw_US
+    0xCE4045534C61746Ellu, // ast_Latn_ES
+    0xA66043414C61746Ellu, // atj_Latn_CA
+    0x617652554379726Cllu, // av_Cyrl_RU
+    0x82C0494E44657661llu, // awa_Deva_IN
+    0x6179424F4C61746Ellu, // ay_Latn_BO
+    0x617A495241726162llu, // az_Arab_IR
+    0x617A415A4C61746Ellu, // az_Latn_AZ
+    0x626152554379726Cllu, // ba_Cyrl_RU
+    0xAC01504B41726162llu, // bal_Arab_PK
+    0xB40149444C61746Ellu, // ban_Latn_ID
+    0xBC014E5044657661llu, // bap_Deva_NP
+    0xC40141544C61746Ellu, // bar_Latn_AT
+    0xC801434D4C61746Ellu, // bas_Latn_CM
+    0xDC01434D42616D75llu, // bax_Bamu_CM
+    0x882149444C61746Ellu, // bbc_Latn_ID
+    0xA421434D4C61746Ellu, // bbj_Latn_CM
+    0xA04143494C61746Ellu, // bci_Latn_CI
+    0x626542594379726Cllu, // be_Cyrl_BY
+    0xA481534441726162llu, // bej_Arab_SD
+    0xB0815A4D4C61746Ellu, // bem_Latn_ZM
+    0xD88149444C61746Ellu, // bew_Latn_ID
+    0xE481545A4C61746Ellu, // bez_Latn_TZ
+    0x8CA1434D4C61746Ellu, // bfd_Latn_CM
+    0xC0A1494E54616D6Cllu, // bfq_Taml_IN
+    0xCCA1504B41726162llu, // bft_Arab_PK
+    0xE0A1494E44657661llu, // bfy_Deva_IN
+    0x626742474379726Cllu, // bg_Cyrl_BG
+    0x88C1494E44657661llu, // bgc_Deva_IN
+    0xB4C1504B41726162llu, // bgn_Arab_PK
+    0xDCC154524772656Bllu, // bgx_Grek_TR
+    0x6268494E4B746869llu, // bh_Kthi_IN
+    0x84E1494E44657661llu, // bhb_Deva_IN
+    0xA0E1494E44657661llu, // bhi_Deva_IN
+    0xA8E150484C61746Ellu, // bhk_Latn_PH
+    0xB8E1494E44657661llu, // bho_Deva_IN
+    0x626956554C61746Ellu, // bi_Latn_VU
+    0xA90150484C61746Ellu, // bik_Latn_PH
+    0xB5014E474C61746Ellu, // bin_Latn_NG
+    0xA521494E44657661llu, // bjj_Deva_IN
+    0xB52149444C61746Ellu, // bjn_Latn_ID
+    0xB141434D4C61746Ellu, // bkm_Latn_CM
+    0xD14150484C61746Ellu, // bku_Latn_PH
+    0xCD61564E54617674llu, // blt_Tavt_VN
+    0x626D4D4C4C61746Ellu, // bm_Latn_ML
+    0xC1814D4C4C61746Ellu, // bmq_Latn_ML
+    0x626E424442656E67llu, // bn_Beng_BD
+    0x626F434E54696274llu, // bo_Tibt_CN
+    0xE1E1494E42656E67llu, // bpy_Beng_IN
+    0xA201495241726162llu, // bqi_Arab_IR
+    0xD60143494C61746Ellu, // bqv_Latn_CI
+    0x627246524C61746Ellu, // br_Latn_FR
+    0x8221494E44657661llu, // bra_Deva_IN
+    0x9E21504B41726162llu, // brh_Arab_PK
+    0xDE21494E44657661llu, // brx_Deva_IN
+    0x627342414C61746Ellu, // bs_Latn_BA
+    0xC2414C5242617373llu, // bsq_Bass_LR
+    0xCA41434D4C61746Ellu, // bss_Latn_CM
+    0xBA6150484C61746Ellu, // bto_Latn_PH
+    0xD661504B44657661llu, // btv_Deva_PK
+    0x828152554379726Cllu, // bua_Cyrl_RU
+    0x8A8159544C61746Ellu, // buc_Latn_YT
+    0x9A8149444C61746Ellu, // bug_Latn_ID
+    0xB281434D4C61746Ellu, // bum_Latn_CM
+    0x86A147514C61746Ellu, // bvb_Latn_GQ
+    0xB701455245746869llu, // byn_Ethi_ER
+    0xD701434D4C61746Ellu, // byv_Latn_CM
+    0x93214D4C4C61746Ellu, // bze_Latn_ML
+    0x636145534C61746Ellu, // ca_Latn_ES
+    0x9C424E474C61746Ellu, // cch_Latn_NG
+    0xBC42494E42656E67llu, // ccp_Beng_IN
+    0xBC42424443616B6Dllu, // ccp_Cakm_BD
+    0x636552554379726Cllu, // ce_Cyrl_RU
+    0x848250484C61746Ellu, // ceb_Latn_PH
+    0x98C255474C61746Ellu, // cgg_Latn_UG
+    0x636847554C61746Ellu, // ch_Latn_GU
+    0xA8E2464D4C61746Ellu, // chk_Latn_FM
+    0xB0E252554379726Cllu, // chm_Cyrl_RU
+    0xB8E255534C61746Ellu, // cho_Latn_US
+    0xBCE243414C61746Ellu, // chp_Latn_CA
+    0xC4E2555343686572llu, // chr_Cher_US
+    0x81224B4841726162llu, // cja_Arab_KH
+    0xB122564E4368616Dllu, // cjm_Cham_VN
+    0x8542495141726162llu, // ckb_Arab_IQ
+    0x636F46524C61746Ellu, // co_Latn_FR
+    0xBDC24547436F7074llu, // cop_Copt_EG
+    0xC9E250484C61746Ellu, // cps_Latn_PH
+    0x6372434143616E73llu, // cr_Cans_CA
+    0xA622434143616E73llu, // crj_Cans_CA
+    0xAA22434143616E73llu, // crk_Cans_CA
+    0xAE22434143616E73llu, // crl_Cans_CA
+    0xB222434143616E73llu, // crm_Cans_CA
+    0xCA2253434C61746Ellu, // crs_Latn_SC
+    0x6373435A4C61746Ellu, // cs_Latn_CZ
+    0x8642504C4C61746Ellu, // csb_Latn_PL
+    0xDA42434143616E73llu, // csw_Cans_CA
+    0x8E624D4D50617563llu, // ctd_Pauc_MM
+    0x637552554379726Cllu, // cu_Cyrl_RU
+    0x63754247476C6167llu, // cu_Glag_BG
+    0x637652554379726Cllu, // cv_Cyrl_RU
+    0x637947424C61746Ellu, // cy_Latn_GB
+    0x6461444B4C61746Ellu, // da_Latn_DK
+    0xA80355534C61746Ellu, // dak_Latn_US
+    0xC40352554379726Cllu, // dar_Cyrl_RU
+    0xD4034B454C61746Ellu, // dav_Latn_KE
+    0x8843494E41726162llu, // dcc_Arab_IN
+    0x646544454C61746Ellu, // de_Latn_DE
+    0xB48343414C61746Ellu, // den_Latn_CA
+    0xC4C343414C61746Ellu, // dgr_Latn_CA
+    0x91234E454C61746Ellu, // dje_Latn_NE
+    0xA5A343494C61746Ellu, // dnj_Latn_CI
+    0xA1C3494E41726162llu, // doi_Arab_IN
+    0x864344454C61746Ellu, // dsb_Latn_DE
+    0xB2634D4C4C61746Ellu, // dtm_Latn_ML
+    0xBE634D594C61746Ellu, // dtp_Latn_MY
+    0x8283434D4C61746Ellu, // dua_Latn_CM
+    0x64764D5654686161llu, // dv_Thaa_MV
+    0xBB03534E4C61746Ellu, // dyo_Latn_SN
+    0xD30342464C61746Ellu, // dyu_Latn_BF
+    0x647A425454696274llu, // dz_Tibt_BT
+    0xD0244B454C61746Ellu, // ebu_Latn_KE
+    0x656547484C61746Ellu, // ee_Latn_GH
+    0xA0A44E474C61746Ellu, // efi_Latn_NG
+    0xACC449544C61746Ellu, // egl_Latn_IT
+    0xE0C4454745677970llu, // egy_Egyp_EG
+    0xE1444D4D4B616C69llu, // eky_Kali_MM
+    0x656C47524772656Bllu, // el_Grek_GR
+    0x656E47424C61746Ellu, // en_Latn_GB
+    0x656E55534C61746Ellu, // en_Latn_US
+    0x656E474253686177llu, // en_Shaw_GB
+    0x657345534C61746Ellu, // es_Latn_ES
+    0x65734D584C61746Ellu, // es_Latn_MX
+    0x657355534C61746Ellu, // es_Latn_US
+    0xD24455534C61746Ellu, // esu_Latn_US
+    0x657445454C61746Ellu, // et_Latn_EE
+    0xCE6449544974616Cllu, // ett_Ital_IT
+    0x657545534C61746Ellu, // eu_Latn_ES
+    0xBAC4434D4C61746Ellu, // ewo_Latn_CM
+    0xCEE445534C61746Ellu, // ext_Latn_ES
+    0x6661495241726162llu, // fa_Arab_IR
+    0xB40547514C61746Ellu, // fan_Latn_GQ
+    0x6666534E4C61746Ellu, // ff_Latn_SN
+    0xB0A54D4C4C61746Ellu, // ffm_Latn_ML
+    0x666946494C61746Ellu, // fi_Latn_FI
+    0x8105534441726162llu, // fia_Arab_SD
+    0xAD0550484C61746Ellu, // fil_Latn_PH
+    0xCD0553454C61746Ellu, // fit_Latn_SE
+    0x666A464A4C61746Ellu, // fj_Latn_FJ
+    0x666F464F4C61746Ellu, // fo_Latn_FO
+    0xB5C5424A4C61746Ellu, // fon_Latn_BJ
+    0x667246524C61746Ellu, // fr_Latn_FR
+    0x8A2555534C61746Ellu, // frc_Latn_US
+    0xBE2546524C61746Ellu, // frp_Latn_FR
+    0xC62544454C61746Ellu, // frr_Latn_DE
+    0xCA2544454C61746Ellu, // frs_Latn_DE
+    0x8E8557464C61746Ellu, // fud_Latn_WF
+    0xC2854E454C61746Ellu, // fuq_Latn_NE
+    0xC68549544C61746Ellu, // fur_Latn_IT
+    0xD6854E474C61746Ellu, // fuv_Latn_NG
+    0xC6A553444C61746Ellu, // fvr_Latn_SD
+    0x66794E4C4C61746Ellu, // fy_Latn_NL
+    0x676149454C61746Ellu, // ga_Latn_IE
+    0x800647484C61746Ellu, // gaa_Latn_GH
+    0x98064D444C61746Ellu, // gag_Latn_MD
+    0xB406434E48616E73llu, // gan_Hans_CN
+    0xE00649444C61746Ellu, // gay_Latn_ID
+    0xB026494E44657661llu, // gbm_Deva_IN
+    0xE426495241726162llu, // gbz_Arab_IR
+    0xC44647464C61746Ellu, // gcr_Latn_GF
+    0x676447424C61746Ellu, // gd_Latn_GB
+    0xE486455445746869llu, // gez_Ethi_ET
+    0xB4C64E5044657661llu, // ggn_Deva_NP
+    0xAD064B494C61746Ellu, // gil_Latn_KI
+    0xA926504B41726162llu, // gjk_Arab_PK
+    0xD126504B41726162llu, // gju_Arab_PK
+    0x676C45534C61746Ellu, // gl_Latn_ES
+    0xA966495241726162llu, // glk_Arab_IR
+    0x676E50594C61746Ellu, // gn_Latn_PY
+    0xB1C6494E44657661llu, // gom_Deva_IN
+    0xB5C6494E54656C75llu, // gon_Telu_IN
+    0xC5C649444C61746Ellu, // gor_Latn_ID
+    0xC9C64E4C4C61746Ellu, // gos_Latn_NL
+    0xCDC65541476F7468llu, // got_Goth_UA
+    0x8A26435943707274llu, // grc_Cprt_CY
+    0x8A2647524C696E62llu, // grc_Linb_GR
+    0xCE26494E42656E67llu, // grt_Beng_IN
+    0xDA4643484C61746Ellu, // gsw_Latn_CH
+    0x6775494E47756A72llu, // gu_Gujr_IN
+    0x868642524C61746Ellu, // gub_Latn_BR
+    0x8A86434F4C61746Ellu, // guc_Latn_CO
+    0xC68647484C61746Ellu, // gur_Latn_GH
+    0xE6864B454C61746Ellu, // guz_Latn_KE
+    0x6776494D4C61746Ellu, // gv_Latn_IM
+    0xC6A64E5044657661llu, // gvr_Deva_NP
+    0xA2C643414C61746Ellu, // gwi_Latn_CA
+    0x68614E474C61746Ellu, // ha_Latn_NG
+    0xA807434E48616E73llu, // hak_Hans_CN
+    0xD80755534C61746Ellu, // haw_Latn_US
+    0xE407414641726162llu, // haz_Arab_AF
+    0x6865494C48656272llu, // he_Hebr_IL
+    0x6869494E44657661llu, // hi_Deva_IN
+    0x9507464A4C61746Ellu, // hif_Latn_FJ
+    0xAD0750484C61746Ellu, // hil_Latn_PH
+    0xD1675452486C7577llu, // hlu_Hluw_TR
+    0x8D87434E506C7264llu, // hmd_Plrd_CN
+    0x8DA7504B41726162llu, // hnd_Arab_PK
+    0x91A7494E44657661llu, // hne_Deva_IN
+    0xA5A74C41486D6E67llu, // hnj_Hmng_LA
+    0xB5A750484C61746Ellu, // hnn_Latn_PH
+    0xB9A7504B41726162llu, // hno_Arab_PK
+    0x686F50474C61746Ellu, // ho_Latn_PG
+    0x89C7494E44657661llu, // hoc_Deva_IN
+    0xA5C7494E44657661llu, // hoj_Deva_IN
+    0x687248524C61746Ellu, // hr_Latn_HR
+    0x864744454C61746Ellu, // hsb_Latn_DE
+    0xB647434E48616E73llu, // hsn_Hans_CN
+    0x687448544C61746Ellu, // ht_Latn_HT
+    0x687548554C61746Ellu, // hu_Latn_HU
+    0x6879414D41726D6Ellu, // hy_Armn_AM
+    0x687A4E414C61746Ellu, // hz_Latn_NA
+    0x696146524C61746Ellu, // ia_Latn_FR
+    0x80284D594C61746Ellu, // iba_Latn_MY
+    0x84284E474C61746Ellu, // ibb_Latn_NG
+    0x696449444C61746Ellu, // id_Latn_ID
+    0x69674E474C61746Ellu, // ig_Latn_NG
+    0x6969434E59696969llu, // ii_Yiii_CN
+    0x696B55534C61746Ellu, // ik_Latn_US
+    0xCD4843414C61746Ellu, // ikt_Latn_CA
+    0xB96850484C61746Ellu, // ilo_Latn_PH
+    0x696E49444C61746Ellu, // in_Latn_ID
+    0x9DA852554379726Cllu, // inh_Cyrl_RU
+    0x697349534C61746Ellu, // is_Latn_IS
+    0x697449544C61746Ellu, // it_Latn_IT
+    0x6975434143616E73llu, // iu_Cans_CA
+    0x6977494C48656272llu, // iw_Hebr_IL
+    0x9F2852554C61746Ellu, // izh_Latn_RU
+    0x6A614A504A70616Ellu, // ja_Jpan_JP
+    0xB0094A4D4C61746Ellu, // jam_Latn_JM
+    0xB8C9434D4C61746Ellu, // jgo_Latn_CM
+    0x6A69554148656272llu, // ji_Hebr_UA
+    0x8989545A4C61746Ellu, // jmc_Latn_TZ
+    0xAD894E5044657661llu, // jml_Deva_NP
+    0xCE89444B4C61746Ellu, // jut_Latn_DK
+    0x6A7649444C61746Ellu, // jv_Latn_ID
+    0x6A7749444C61746Ellu, // jw_Latn_ID
+    0x6B61474547656F72llu, // ka_Geor_GE
+    0x800A555A4379726Cllu, // kaa_Cyrl_UZ
+    0x840A445A4C61746Ellu, // kab_Latn_DZ
+    0x880A4D4D4C61746Ellu, // kac_Latn_MM
+    0xA40A4E474C61746Ellu, // kaj_Latn_NG
+    0xB00A4B454C61746Ellu, // kam_Latn_KE
+    0xB80A4D4C4C61746Ellu, // kao_Latn_ML
+    0x8C2A52554379726Cllu, // kbd_Cyrl_RU
+    0x984A4E474C61746Ellu, // kcg_Latn_NG
+    0xA84A5A574C61746Ellu, // kck_Latn_ZW
+    0x906A545A4C61746Ellu, // kde_Latn_TZ
+    0xCC6A544854686169llu, // kdt_Thai_TH
+    0x808A43564C61746Ellu, // kea_Latn_CV
+    0xB48A434D4C61746Ellu, // ken_Latn_CM
+    0xB8AA43494C61746Ellu, // kfo_Latn_CI
+    0xC4AA494E44657661llu, // kfr_Deva_IN
+    0xE0AA494E44657661llu, // kfy_Deva_IN
+    0x6B6743444C61746Ellu, // kg_Latn_CD
+    0x90CA49444C61746Ellu, // kge_Latn_ID
+    0xBCCA42524C61746Ellu, // kgp_Latn_BR
+    0x80EA494E4C61746Ellu, // kha_Latn_IN
+    0x84EA434E54616C75llu, // khb_Talu_CN
+    0xB4EA494E44657661llu, // khn_Deva_IN
+    0xC0EA4D4C4C61746Ellu, // khq_Latn_ML
+    0xCCEA494E4D796D72llu, // kht_Mymr_IN
+    0xD8EA504B41726162llu, // khw_Arab_PK
+    0x6B694B454C61746Ellu, // ki_Latn_KE
+    0xD10A54524C61746Ellu, // kiu_Latn_TR
+    0x6B6A4E414C61746Ellu, // kj_Latn_NA
+    0x992A4C414C616F6Fllu, // kjg_Laoo_LA
+    0x6B6B434E41726162llu, // kk_Arab_CN
+    0x6B6B4B5A4379726Cllu, // kk_Cyrl_KZ
+    0xA54A434D4C61746Ellu, // kkj_Latn_CM
+    0x6B6C474C4C61746Ellu, // kl_Latn_GL
+    0xB56A4B454C61746Ellu, // kln_Latn_KE
+    0x6B6D4B484B686D72llu, // km_Khmr_KH
+    0x858A414F4C61746Ellu, // kmb_Latn_AO
+    0x6B6E494E4B6E6461llu, // kn_Knda_IN
+    0x6B6F4B524B6F7265llu, // ko_Kore_KR
+    0xA1CA52554379726Cllu, // koi_Cyrl_RU
+    0xA9CA494E44657661llu, // kok_Deva_IN
+    0xC9CA464D4C61746Ellu, // kos_Latn_FM
+    0x91EA4C524C61746Ellu, // kpe_Latn_LR
+    0x8A2A52554379726Cllu, // krc_Cyrl_RU
+    0xA22A534C4C61746Ellu, // kri_Latn_SL
+    0xA62A50484C61746Ellu, // krj_Latn_PH
+    0xAE2A52554C61746Ellu, // krl_Latn_RU
+    0xD22A494E44657661llu, // kru_Deva_IN
+    0x6B73494E41726162llu, // ks_Arab_IN
+    0x864A545A4C61746Ellu, // ksb_Latn_TZ
+    0x964A434D4C61746Ellu, // ksf_Latn_CM
+    0x9E4A44454C61746Ellu, // ksh_Latn_DE
+    0x6B75495141726162llu, // ku_Arab_IQ
+    0x6B7554524C61746Ellu, // ku_Latn_TR
+    0xB28A52554379726Cllu, // kum_Cyrl_RU
+    0x6B7652554379726Cllu, // kv_Cyrl_RU
+    0xC6AA49444C61746Ellu, // kvr_Latn_ID
+    0xDEAA504B41726162llu, // kvx_Arab_PK
+    0x6B7747424C61746Ellu, // kw_Latn_GB
+    0xB2EA544854686169llu, // kxm_Thai_TH
+    0xBEEA504B41726162llu, // kxp_Arab_PK
+    0x6B79434E41726162llu, // ky_Arab_CN
+    0x6B794B474379726Cllu, // ky_Cyrl_KG
+    0x6B7954524C61746Ellu, // ky_Latn_TR
+    0x6C6156414C61746Ellu, // la_Latn_VA
+    0x840B47524C696E61llu, // lab_Lina_GR
+    0x8C0B494C48656272llu, // lad_Hebr_IL
+    0x980B545A4C61746Ellu, // lag_Latn_TZ
+    0x9C0B504B41726162llu, // lah_Arab_PK
+    0xA40B55474C61746Ellu, // laj_Latn_UG
+    0x6C624C554C61746Ellu, // lb_Latn_LU
+    0x902B52554379726Cllu, // lbe_Cyrl_RU
+    0xD82B49444C61746Ellu, // lbw_Latn_ID
+    0xBC4B434E54686169llu, // lcp_Thai_CN
+    0xBC8B494E4C657063llu, // lep_Lepc_IN
+    0xE48B52554379726Cllu, // lez_Cyrl_RU
+    0x6C6755474C61746Ellu, // lg_Latn_UG
+    0x6C694E4C4C61746Ellu, // li_Latn_NL
+    0x950B4E5044657661llu, // lif_Deva_NP
+    0x950B494E4C696D62llu, // lif_Limb_IN
+    0xA50B49544C61746Ellu, // lij_Latn_IT
+    0xC90B434E4C697375llu, // lis_Lisu_CN
+    0xBD2B49444C61746Ellu, // ljp_Latn_ID
+    0xA14B495241726162llu, // lki_Arab_IR
+    0xCD4B55534C61746Ellu, // lkt_Latn_US
+    0xB58B494E54656C75llu, // lmn_Telu_IN
+    0xB98B49544C61746Ellu, // lmo_Latn_IT
+    0x6C6E43444C61746Ellu, // ln_Latn_CD
+    0x6C6F4C414C616F6Fllu, // lo_Laoo_LA
+    0xADCB43444C61746Ellu, // lol_Latn_CD
+    0xE5CB5A4D4C61746Ellu, // loz_Latn_ZM
+    0x8A2B495241726162llu, // lrc_Arab_IR
+    0x6C744C544C61746Ellu, // lt_Latn_LT
+    0x9A6B4C564C61746Ellu, // ltg_Latn_LV
+    0x6C7543444C61746Ellu, // lu_Latn_CD
+    0x828B43444C61746Ellu, // lua_Latn_CD
+    0xBA8B4B454C61746Ellu, // luo_Latn_KE
+    0xE28B4B454C61746Ellu, // luy_Latn_KE
+    0xE68B495241726162llu, // luz_Arab_IR
+    0x6C764C564C61746Ellu, // lv_Latn_LV
+    0xAECB544854686169llu, // lwl_Thai_TH
+    0x9F2B434E48616E73llu, // lzh_Hans_CN
+    0xE72B54524C61746Ellu, // lzz_Latn_TR
+    0x8C0C49444C61746Ellu, // mad_Latn_ID
+    0x940C434D4C61746Ellu, // maf_Latn_CM
+    0x980C494E44657661llu, // mag_Deva_IN
+    0xA00C494E44657661llu, // mai_Deva_IN
+    0xA80C49444C61746Ellu, // mak_Latn_ID
+    0xB40C474D4C61746Ellu, // man_Latn_GM
+    0xB40C474E4E6B6F6Fllu, // man_Nkoo_GN
+    0xC80C4B454C61746Ellu, // mas_Latn_KE
+    0xE40C4D584C61746Ellu, // maz_Latn_MX
+    0x946C52554379726Cllu, // mdf_Cyrl_RU
+    0x9C6C50484C61746Ellu, // mdh_Latn_PH
+    0xC46C49444C61746Ellu, // mdr_Latn_ID
+    0xB48C534C4C61746Ellu, // men_Latn_SL
+    0xC48C4B454C61746Ellu, // mer_Latn_KE
+    0x80AC544841726162llu, // mfa_Arab_TH
+    0x90AC4D554C61746Ellu, // mfe_Latn_MU
+    0x6D674D474C61746Ellu, // mg_Latn_MG
+    0x9CCC4D5A4C61746Ellu, // mgh_Latn_MZ
+    0xB8CC434D4C61746Ellu, // mgo_Latn_CM
+    0xBCCC4E5044657661llu, // mgp_Deva_NP
+    0xE0CC545A4C61746Ellu, // mgy_Latn_TZ
+    0x6D684D484C61746Ellu, // mh_Latn_MH
+    0x6D694E5A4C61746Ellu, // mi_Latn_NZ
+    0xB50C49444C61746Ellu, // min_Latn_ID
+    0xC90C495148617472llu, // mis_Hatr_IQ
+    0x6D6B4D4B4379726Cllu, // mk_Cyrl_MK
+    0x6D6C494E4D6C796Dllu, // ml_Mlym_IN
+    0xC96C53444C61746Ellu, // mls_Latn_SD
+    0x6D6E4D4E4379726Cllu, // mn_Cyrl_MN
+    0x6D6E434E4D6F6E67llu, // mn_Mong_CN
+    0xA1AC494E42656E67llu, // mni_Beng_IN
+    0xD9AC4D4D4D796D72llu, // mnw_Mymr_MM
+    0x91CC43414C61746Ellu, // moe_Latn_CA
+    0x9DCC43414C61746Ellu, // moh_Latn_CA
+    0xC9CC42464C61746Ellu, // mos_Latn_BF
+    0x6D72494E44657661llu, // mr_Deva_IN
+    0x8E2C4E5044657661llu, // mrd_Deva_NP
+    0xA62C52554379726Cllu, // mrj_Cyrl_RU
+    0xD22C42444D726F6Fllu, // mru_Mroo_BD
+    0x6D734D594C61746Ellu, // ms_Latn_MY
+    0x6D744D544C61746Ellu, // mt_Latn_MT
+    0xC66C494E44657661llu, // mtr_Deva_IN
+    0x828C434D4C61746Ellu, // mua_Latn_CM
+    0xCA8C55534C61746Ellu, // mus_Latn_US
+    0xE2AC504B41726162llu, // mvy_Arab_PK
+    0xAACC4D4C4C61746Ellu, // mwk_Latn_ML
+    0xC6CC494E44657661llu, // mwr_Deva_IN
+    0xD6CC49444C61746Ellu, // mwv_Latn_ID
+    0x8AEC5A574C61746Ellu, // mxc_Latn_ZW
+    0x6D794D4D4D796D72llu, // my_Mymr_MM
+    0xD70C52554379726Cllu, // myv_Cyrl_RU
+    0xDF0C55474C61746Ellu, // myx_Latn_UG
+    0xE70C49524D616E64llu, // myz_Mand_IR
+    0xB72C495241726162llu, // mzn_Arab_IR
+    0x6E614E524C61746Ellu, // na_Latn_NR
+    0xB40D434E48616E73llu, // nan_Hans_CN
+    0xBC0D49544C61746Ellu, // nap_Latn_IT
+    0xC00D4E414C61746Ellu, // naq_Latn_NA
+    0x6E624E4F4C61746Ellu, // nb_Latn_NO
+    0x9C4D4D584C61746Ellu, // nch_Latn_MX
+    0x6E645A574C61746Ellu, // nd_Latn_ZW
+    0x886D4D5A4C61746Ellu, // ndc_Latn_MZ
+    0xC86D44454C61746Ellu, // nds_Latn_DE
+    0x6E654E5044657661llu, // ne_Deva_NP
+    0xD88D4E5044657661llu, // new_Deva_NP
+    0x6E674E414C61746Ellu, // ng_Latn_NA
+    0xACCD4D5A4C61746Ellu, // ngl_Latn_MZ
+    0x90ED4D584C61746Ellu, // nhe_Latn_MX
+    0xD8ED4D584C61746Ellu, // nhw_Latn_MX
+    0xA50D49444C61746Ellu, // nij_Latn_ID
+    0xD10D4E554C61746Ellu, // niu_Latn_NU
+    0xB92D494E4C61746Ellu, // njo_Latn_IN
+    0x6E6C4E4C4C61746Ellu, // nl_Latn_NL
+    0x998D434D4C61746Ellu, // nmg_Latn_CM
+    0x6E6E4E4F4C61746Ellu, // nn_Latn_NO
+    0x9DAD434D4C61746Ellu, // nnh_Latn_CM
+    0x6E6F4E4F4C61746Ellu, // no_Latn_NO
+    0x8DCD54484C616E61llu, // nod_Lana_TH
+    0x91CD494E44657661llu, // noe_Deva_IN
+    0xB5CD534552756E72llu, // non_Runr_SE
+    0xBA0D474E4E6B6F6Fllu, // nqo_Nkoo_GN
+    0x6E725A414C61746Ellu, // nr_Latn_ZA
+    0xAA4D434143616E73llu, // nsk_Cans_CA
+    0xBA4D5A414C61746Ellu, // nso_Latn_ZA
+    0xCA8D53534C61746Ellu, // nus_Latn_SS
+    0x6E7655534C61746Ellu, // nv_Latn_US
+    0xC2ED434E4C61746Ellu, // nxq_Latn_CN
+    0x6E794D574C61746Ellu, // ny_Latn_MW
+    0xB30D545A4C61746Ellu, // nym_Latn_TZ
+    0xB70D55474C61746Ellu, // nyn_Latn_UG
+    0xA32D47484C61746Ellu, // nzi_Latn_GH
+    0x6F6346524C61746Ellu, // oc_Latn_FR
+    0x6F6D45544C61746Ellu, // om_Latn_ET
+    0x6F72494E4F727961llu, // or_Orya_IN
+    0x6F7347454379726Cllu, // os_Cyrl_GE
+    0xAA6E4D4E4F726B68llu, // otk_Orkh_MN
+    0x7061504B41726162llu, // pa_Arab_PK
+    0x7061494E47757275llu, // pa_Guru_IN
+    0x980F50484C61746Ellu, // pag_Latn_PH
+    0xAC0F495250686C69llu, // pal_Phli_IR
+    0xAC0F434E50686C70llu, // pal_Phlp_CN
+    0xB00F50484C61746Ellu, // pam_Latn_PH
+    0xBC0F41574C61746Ellu, // pap_Latn_AW
+    0xD00F50574C61746Ellu, // pau_Latn_PW
+    0x8C4F46524C61746Ellu, // pcd_Latn_FR
+    0xB04F4E474C61746Ellu, // pcm_Latn_NG
+    0x886F55534C61746Ellu, // pdc_Latn_US
+    0xCC6F43414C61746Ellu, // pdt_Latn_CA
+    0xB88F49525870656Fllu, // peo_Xpeo_IR
+    0xACAF44454C61746Ellu, // pfl_Latn_DE
+    0xB4EF4C4250686E78llu, // phn_Phnx_LB
+    0x814F494E42726168llu, // pka_Brah_IN
+    0xB94F4B454C61746Ellu, // pko_Latn_KE
+    0x706C504C4C61746Ellu, // pl_Latn_PL
+    0xC98F49544C61746Ellu, // pms_Latn_IT
+    0xCDAF47524772656Bllu, // pnt_Grek_GR
+    0xB5CF464D4C61746Ellu, // pon_Latn_FM
+    0x822F504B4B686172llu, // pra_Khar_PK
+    0x8E2F495241726162llu, // prd_Arab_IR
+    0x7073414641726162llu, // ps_Arab_AF
+    0x707442524C61746Ellu, // pt_Latn_BR
+    0xD28F47414C61746Ellu, // puu_Latn_GA
+    0x717550454C61746Ellu, // qu_Latn_PE
+    0x8A9047544C61746Ellu, // quc_Latn_GT
+    0x9A9045434C61746Ellu, // qug_Latn_EC
+    0xA411494E44657661llu, // raj_Deva_IN
+    0x945152454C61746Ellu, // rcf_Latn_RE
+    0xA49149444C61746Ellu, // rej_Latn_ID
+    0xB4D149544C61746Ellu, // rgn_Latn_IT
+    0x8111494E4C61746Ellu, // ria_Latn_IN
+    0x95114D4154666E67llu, // rif_Tfng_MA
+    0xC9314E5044657661llu, // rjs_Deva_NP
+    0xCD51424442656E67llu, // rkt_Beng_BD
+    0x726D43484C61746Ellu, // rm_Latn_CH
+    0x959146494C61746Ellu, // rmf_Latn_FI
+    0xB99143484C61746Ellu, // rmo_Latn_CH
+    0xCD91495241726162llu, // rmt_Arab_IR
+    0xD19153454C61746Ellu, // rmu_Latn_SE
+    0x726E42494C61746Ellu, // rn_Latn_BI
+    0x99B14D5A4C61746Ellu, // rng_Latn_MZ
+    0x726F524F4C61746Ellu, // ro_Latn_RO
+    0x85D149444C61746Ellu, // rob_Latn_ID
+    0x95D1545A4C61746Ellu, // rof_Latn_TZ
+    0xB271464A4C61746Ellu, // rtm_Latn_FJ
+    0x727552554379726Cllu, // ru_Cyrl_RU
+    0x929155414379726Cllu, // rue_Cyrl_UA
+    0x9A9153424C61746Ellu, // rug_Latn_SB
+    0x727752574C61746Ellu, // rw_Latn_RW
+    0xAAD1545A4C61746Ellu, // rwk_Latn_TZ
+    0xD3114A504B616E61llu, // ryu_Kana_JP
+    0x7361494E44657661llu, // sa_Deva_IN
+    0x941247484C61746Ellu, // saf_Latn_GH
+    0x9C1252554379726Cllu, // sah_Cyrl_RU
+    0xC0124B454C61746Ellu, // saq_Latn_KE
+    0xC81249444C61746Ellu, // sas_Latn_ID
+    0xCC12494E4C61746Ellu, // sat_Latn_IN
+    0xE412494E53617572llu, // saz_Saur_IN
+    0xBC32545A4C61746Ellu, // sbp_Latn_TZ
+    0x736349544C61746Ellu, // sc_Latn_IT
+    0xA852494E44657661llu, // sck_Deva_IN
+    0xB45249544C61746Ellu, // scn_Latn_IT
+    0xB85247424C61746Ellu, // sco_Latn_GB
+    0xC85243414C61746Ellu, // scs_Latn_CA
+    0x7364504B41726162llu, // sd_Arab_PK
+    0x7364494E44657661llu, // sd_Deva_IN
+    0x7364494E4B686F6Allu, // sd_Khoj_IN
+    0x7364494E53696E64llu, // sd_Sind_IN
+    0x887249544C61746Ellu, // sdc_Latn_IT
+    0x9C72495241726162llu, // sdh_Arab_IR
+    0x73654E4F4C61746Ellu, // se_Latn_NO
+    0x949243494C61746Ellu, // sef_Latn_CI
+    0x9C924D5A4C61746Ellu, // seh_Latn_MZ
+    0xA0924D584C61746Ellu, // sei_Latn_MX
+    0xC8924D4C4C61746Ellu, // ses_Latn_ML
+    0x736743464C61746Ellu, // sg_Latn_CF
+    0x80D249454F67616Dllu, // sga_Ogam_IE
+    0xC8D24C544C61746Ellu, // sgs_Latn_LT
+    0xA0F24D4154666E67llu, // shi_Tfng_MA
+    0xB4F24D4D4D796D72llu, // shn_Mymr_MM
+    0x73694C4B53696E68llu, // si_Sinh_LK
+    0x8D1245544C61746Ellu, // sid_Latn_ET
+    0x736B534B4C61746Ellu, // sk_Latn_SK
+    0xC552504B41726162llu, // skr_Arab_PK
+    0x736C53494C61746Ellu, // sl_Latn_SI
+    0xA172504C4C61746Ellu, // sli_Latn_PL
+    0xE17249444C61746Ellu, // sly_Latn_ID
+    0x736D57534C61746Ellu, // sm_Latn_WS
+    0x819253454C61746Ellu, // sma_Latn_SE
+    0xA59253454C61746Ellu, // smj_Latn_SE
+    0xB59246494C61746Ellu, // smn_Latn_FI
+    0xBD92494C53616D72llu, // smp_Samr_IL
+    0xC99246494C61746Ellu, // sms_Latn_FI
+    0x736E5A574C61746Ellu, // sn_Latn_ZW
+    0xA9B24D4C4C61746Ellu, // snk_Latn_ML
+    0x736F534F4C61746Ellu, // so_Latn_SO
+    0xD1D2544854686169llu, // sou_Thai_TH
+    0x7371414C4C61746Ellu, // sq_Latn_AL
+    0x737252534379726Cllu, // sr_Cyrl_RS
+    0x737252534C61746Ellu, // sr_Latn_RS
+    0x8632494E536F7261llu, // srb_Sora_IN
+    0xB63253524C61746Ellu, // srn_Latn_SR
+    0xC632534E4C61746Ellu, // srr_Latn_SN
+    0xDE32494E44657661llu, // srx_Deva_IN
+    0x73735A414C61746Ellu, // ss_Latn_ZA
+    0xE25245524C61746Ellu, // ssy_Latn_ER
+    0x73745A414C61746Ellu, // st_Latn_ZA
+    0xC27244454C61746Ellu, // stq_Latn_DE
+    0x737549444C61746Ellu, // su_Latn_ID
+    0xAA92545A4C61746Ellu, // suk_Latn_TZ
+    0xCA92474E4C61746Ellu, // sus_Latn_GN
+    0x737653454C61746Ellu, // sv_Latn_SE
+    0x7377545A4C61746Ellu, // sw_Latn_TZ
+    0x86D2595441726162llu, // swb_Arab_YT
+    0x8AD243444C61746Ellu, // swc_Latn_CD
+    0x9AD244454C61746Ellu, // swg_Latn_DE
+    0xD6D2494E44657661llu, // swv_Deva_IN
+    0xB6F249444C61746Ellu, // sxn_Latn_ID
+    0xAF12424442656E67llu, // syl_Beng_BD
+    0xC712495153797263llu, // syr_Syrc_IQ
+    0xAF32504C4C61746Ellu, // szl_Latn_PL
+    0x7461494E54616D6Cllu, // ta_Taml_IN
+    0xA4134E5044657661llu, // taj_Deva_NP
+    0xD83350484C61746Ellu, // tbw_Latn_PH
+    0xE053494E4B6E6461llu, // tcy_Knda_IN
+    0x8C73434E54616C65llu, // tdd_Tale_CN
+    0x98734E5044657661llu, // tdg_Deva_NP
+    0x9C734E5044657661llu, // tdh_Deva_NP
+    0x7465494E54656C75llu, // te_Telu_IN
+    0xB093534C4C61746Ellu, // tem_Latn_SL
+    0xB89355474C61746Ellu, // teo_Latn_UG
+    0xCC93544C4C61746Ellu, // tet_Latn_TL
+    0x7467504B41726162llu, // tg_Arab_PK
+    0x7467544A4379726Cllu, // tg_Cyrl_TJ
+    0x7468544854686169llu, // th_Thai_TH
+    0xACF34E5044657661llu, // thl_Deva_NP
+    0xC0F34E5044657661llu, // thq_Deva_NP
+    0xC4F34E5044657661llu, // thr_Deva_NP
+    0x7469455445746869llu, // ti_Ethi_ET
+    0x9913455245746869llu, // tig_Ethi_ER
+    0xD5134E474C61746Ellu, // tiv_Latn_NG
+    0x746B544D4C61746Ellu, // tk_Latn_TM
+    0xAD53544B4C61746Ellu, // tkl_Latn_TK
+    0xC553415A4C61746Ellu, // tkr_Latn_AZ
+    0xCD534E5044657661llu, // tkt_Deva_NP
+    0x746C50484C61746Ellu, // tl_Latn_PH
+    0xE173415A4C61746Ellu, // tly_Latn_AZ
+    0x9D934E454C61746Ellu, // tmh_Latn_NE
+    0x746E5A414C61746Ellu, // tn_Latn_ZA
+    0x746F544F4C61746Ellu, // to_Latn_TO
+    0x99D34D574C61746Ellu, // tog_Latn_MW
+    0xA1F350474C61746Ellu, // tpi_Latn_PG
+    0x747254524C61746Ellu, // tr_Latn_TR
+    0xD23354524C61746Ellu, // tru_Latn_TR
+    0xD63354574C61746Ellu, // trv_Latn_TW
+    0x74735A414C61746Ellu, // ts_Latn_ZA
+    0x8E5347524772656Bllu, // tsd_Grek_GR
+    0x96534E5044657661llu, // tsf_Deva_NP
+    0x9A5350484C61746Ellu, // tsg_Latn_PH
+    0xA653425454696274llu, // tsj_Tibt_BT
+    0x747452554379726Cllu, // tt_Cyrl_RU
+    0xA67355474C61746Ellu, // ttj_Latn_UG
+    0xCA73544854686169llu, // tts_Thai_TH
+    0xCE73415A4C61746Ellu, // ttt_Latn_AZ
+    0xB2934D574C61746Ellu, // tum_Latn_MW
+    0xAEB354564C61746Ellu, // tvl_Latn_TV
+    0xC2D34E454C61746Ellu, // twq_Latn_NE
+    0x747950464C61746Ellu, // ty_Latn_PF
+    0xD71352554379726Cllu, // tyv_Cyrl_RU
+    0xB3334D414C61746Ellu, // tzm_Latn_MA
+    0xB07452554379726Cllu, // udm_Cyrl_RU
+    0x7567434E41726162llu, // ug_Arab_CN
+    0x75674B5A4379726Cllu, // ug_Cyrl_KZ
+    0x80D4535955676172llu, // uga_Ugar_SY
+    0x756B55414379726Cllu, // uk_Cyrl_UA
+    0xA174464D4C61746Ellu, // uli_Latn_FM
+    0x8594414F4C61746Ellu, // umb_Latn_AO
+    0xC5B4494E42656E67llu, // unr_Beng_IN
+    0xC5B44E5044657661llu, // unr_Deva_NP
+    0xDDB4494E42656E67llu, // unx_Beng_IN
+    0x7572504B41726162llu, // ur_Arab_PK
+    0x757A414641726162llu, // uz_Arab_AF
+    0x757A555A4C61746Ellu, // uz_Latn_UZ
+    0xA0154C5256616969llu, // vai_Vaii_LR
+    0x76655A414C61746Ellu, // ve_Latn_ZA
+    0x889549544C61746Ellu, // vec_Latn_IT
+    0xBC9552554C61746Ellu, // vep_Latn_RU
+    0x7669564E4C61746Ellu, // vi_Latn_VN
+    0x891553584C61746Ellu, // vic_Latn_SX
+    0xC97542454C61746Ellu, // vls_Latn_BE
+    0x959544454C61746Ellu, // vmf_Latn_DE
+    0xD9954D5A4C61746Ellu, // vmw_Latn_MZ
+    0xCDD552554C61746Ellu, // vot_Latn_RU
+    0xBA3545454C61746Ellu, // vro_Latn_EE
+    0xB695545A4C61746Ellu, // vun_Latn_TZ
+    0x776142454C61746Ellu, // wa_Latn_BE
+    0x901643484C61746Ellu, // wae_Latn_CH
+    0xAC16455445746869llu, // wal_Ethi_ET
+    0xC41650484C61746Ellu, // war_Latn_PH
+    0xBC3641554C61746Ellu, // wbp_Latn_AU
+    0xC036494E54656C75llu, // wbq_Telu_IN
+    0xC436494E44657661llu, // wbr_Deva_IN
+    0xC97657464C61746Ellu, // wls_Latn_WF
+    0xA1B64B4D41726162llu, // wni_Arab_KM
+    0x776F534E4C61746Ellu, // wo_Latn_SN
+    0xB276494E44657661llu, // wtm_Deva_IN
+    0xD296434E48616E73llu, // wuu_Hans_CN
+    0xD41742524C61746Ellu, // xav_Latn_BR
+    0xC457545243617269llu, // xcr_Cari_TR
+    0x78685A414C61746Ellu, // xh_Latn_ZA
+    0x897754524C796369llu, // xlc_Lyci_TR
+    0x8D7754524C796469llu, // xld_Lydi_TR
+    0x9597474547656F72llu, // xmf_Geor_GE
+    0xB597434E4D616E69llu, // xmn_Mani_CN
+    0xC59753444D657263llu, // xmr_Merc_SD
+    0x81B753414E617262llu, // xna_Narb_SA
+    0xC5B7494E44657661llu, // xnr_Deva_IN
+    0x99D755474C61746Ellu, // xog_Latn_UG
+    0xC5F7495250727469llu, // xpr_Prti_IR
+    0x8257594553617262llu, // xsa_Sarb_YE
+    0xC6574E5044657661llu, // xsr_Deva_NP
+    0xB8184D5A4C61746Ellu, // yao_Latn_MZ
+    0xBC18464D4C61746Ellu, // yap_Latn_FM
+    0xD418434D4C61746Ellu, // yav_Latn_CM
+    0x8438434D4C61746Ellu, // ybb_Latn_CM
+    0x796F4E474C61746Ellu, // yo_Latn_NG
+    0xAE3842524C61746Ellu, // yrl_Latn_BR
+    0x82984D584C61746Ellu, // yua_Latn_MX
+    0x7A61434E4C61746Ellu, // za_Latn_CN
+    0x981953444C61746Ellu, // zag_Latn_SD
+    0xA4794B4D41726162llu, // zdj_Arab_KM
+    0x80994E4C4C61746Ellu, // zea_Latn_NL
+    0x9CD94D4154666E67llu, // zgh_Tfng_MA
+    0x7A685457426F706Fllu, // zh_Bopo_TW
+    0x7A68434E48616E73llu, // zh_Hans_CN
+    0x7A68545748616E74llu, // zh_Hant_TW
+    0xA1994D594C61746Ellu, // zmi_Latn_MY
+    0x7A755A414C61746Ellu, // zu_Latn_ZA
+    0x833954524C61746Ellu, // zza_Latn_TR
+});
+
+const std::unordered_map<uint32_t, uint32_t> ARAB_PARENTS({
+    {0x6172445Au, 0x61729420u}, // ar-DZ -> ar-015
+    {0x61724548u, 0x61729420u}, // ar-EH -> ar-015
+    {0x61724C59u, 0x61729420u}, // ar-LY -> ar-015
+    {0x61724D41u, 0x61729420u}, // ar-MA -> ar-015
+    {0x6172544Eu, 0x61729420u}, // ar-TN -> ar-015
+});
+
+const std::unordered_map<uint32_t, uint32_t> HANT_PARENTS({
+    {0x7A684D4Fu, 0x7A68484Bu}, // zh-Hant-MO -> zh-Hant-HK
+});
+
+const std::unordered_map<uint32_t, uint32_t> LATN_PARENTS({
+    {0x656E80A1u, 0x656E8400u}, // en-150 -> en-001
+    {0x656E4147u, 0x656E8400u}, // en-AG -> en-001
+    {0x656E4149u, 0x656E8400u}, // en-AI -> en-001
+    {0x656E4154u, 0x656E80A1u}, // en-AT -> en-150
+    {0x656E4155u, 0x656E8400u}, // en-AU -> en-001
+    {0x656E4242u, 0x656E8400u}, // en-BB -> en-001
+    {0x656E4245u, 0x656E8400u}, // en-BE -> en-001
+    {0x656E424Du, 0x656E8400u}, // en-BM -> en-001
+    {0x656E4253u, 0x656E8400u}, // en-BS -> en-001
+    {0x656E4257u, 0x656E8400u}, // en-BW -> en-001
+    {0x656E425Au, 0x656E8400u}, // en-BZ -> en-001
+    {0x656E4341u, 0x656E8400u}, // en-CA -> en-001
+    {0x656E4343u, 0x656E8400u}, // en-CC -> en-001
+    {0x656E4348u, 0x656E80A1u}, // en-CH -> en-150
+    {0x656E434Bu, 0x656E8400u}, // en-CK -> en-001
+    {0x656E434Du, 0x656E8400u}, // en-CM -> en-001
+    {0x656E4358u, 0x656E8400u}, // en-CX -> en-001
+    {0x656E4359u, 0x656E8400u}, // en-CY -> en-001
+    {0x656E4445u, 0x656E80A1u}, // en-DE -> en-150
+    {0x656E4447u, 0x656E8400u}, // en-DG -> en-001
+    {0x656E444Bu, 0x656E80A1u}, // en-DK -> en-150
+    {0x656E444Du, 0x656E8400u}, // en-DM -> en-001
+    {0x656E4552u, 0x656E8400u}, // en-ER -> en-001
+    {0x656E4649u, 0x656E80A1u}, // en-FI -> en-150
+    {0x656E464Au, 0x656E8400u}, // en-FJ -> en-001
+    {0x656E464Bu, 0x656E8400u}, // en-FK -> en-001
+    {0x656E464Du, 0x656E8400u}, // en-FM -> en-001
+    {0x656E4742u, 0x656E8400u}, // en-GB -> en-001
+    {0x656E4744u, 0x656E8400u}, // en-GD -> en-001
+    {0x656E4747u, 0x656E8400u}, // en-GG -> en-001
+    {0x656E4748u, 0x656E8400u}, // en-GH -> en-001
+    {0x656E4749u, 0x656E8400u}, // en-GI -> en-001
+    {0x656E474Du, 0x656E8400u}, // en-GM -> en-001
+    {0x656E4759u, 0x656E8400u}, // en-GY -> en-001
+    {0x656E484Bu, 0x656E8400u}, // en-HK -> en-001
+    {0x656E4945u, 0x656E8400u}, // en-IE -> en-001
+    {0x656E494Cu, 0x656E8400u}, // en-IL -> en-001
+    {0x656E494Du, 0x656E8400u}, // en-IM -> en-001
+    {0x656E494Eu, 0x656E8400u}, // en-IN -> en-001
+    {0x656E494Fu, 0x656E8400u}, // en-IO -> en-001
+    {0x656E4A45u, 0x656E8400u}, // en-JE -> en-001
+    {0x656E4A4Du, 0x656E8400u}, // en-JM -> en-001
+    {0x656E4B45u, 0x656E8400u}, // en-KE -> en-001
+    {0x656E4B49u, 0x656E8400u}, // en-KI -> en-001
+    {0x656E4B4Eu, 0x656E8400u}, // en-KN -> en-001
+    {0x656E4B59u, 0x656E8400u}, // en-KY -> en-001
+    {0x656E4C43u, 0x656E8400u}, // en-LC -> en-001
+    {0x656E4C52u, 0x656E8400u}, // en-LR -> en-001
+    {0x656E4C53u, 0x656E8400u}, // en-LS -> en-001
+    {0x656E4D47u, 0x656E8400u}, // en-MG -> en-001
+    {0x656E4D4Fu, 0x656E8400u}, // en-MO -> en-001
+    {0x656E4D53u, 0x656E8400u}, // en-MS -> en-001
+    {0x656E4D54u, 0x656E8400u}, // en-MT -> en-001
+    {0x656E4D55u, 0x656E8400u}, // en-MU -> en-001
+    {0x656E4D57u, 0x656E8400u}, // en-MW -> en-001
+    {0x656E4D59u, 0x656E8400u}, // en-MY -> en-001
+    {0x656E4E41u, 0x656E8400u}, // en-NA -> en-001
+    {0x656E4E46u, 0x656E8400u}, // en-NF -> en-001
+    {0x656E4E47u, 0x656E8400u}, // en-NG -> en-001
+    {0x656E4E4Cu, 0x656E80A1u}, // en-NL -> en-150
+    {0x656E4E52u, 0x656E8400u}, // en-NR -> en-001
+    {0x656E4E55u, 0x656E8400u}, // en-NU -> en-001
+    {0x656E4E5Au, 0x656E8400u}, // en-NZ -> en-001
+    {0x656E5047u, 0x656E8400u}, // en-PG -> en-001
+    {0x656E5048u, 0x656E8400u}, // en-PH -> en-001
+    {0x656E504Bu, 0x656E8400u}, // en-PK -> en-001
+    {0x656E504Eu, 0x656E8400u}, // en-PN -> en-001
+    {0x656E5057u, 0x656E8400u}, // en-PW -> en-001
+    {0x656E5257u, 0x656E8400u}, // en-RW -> en-001
+    {0x656E5342u, 0x656E8400u}, // en-SB -> en-001
+    {0x656E5343u, 0x656E8400u}, // en-SC -> en-001
+    {0x656E5344u, 0x656E8400u}, // en-SD -> en-001
+    {0x656E5345u, 0x656E80A1u}, // en-SE -> en-150
+    {0x656E5347u, 0x656E8400u}, // en-SG -> en-001
+    {0x656E5348u, 0x656E8400u}, // en-SH -> en-001
+    {0x656E5349u, 0x656E80A1u}, // en-SI -> en-150
+    {0x656E534Cu, 0x656E8400u}, // en-SL -> en-001
+    {0x656E5353u, 0x656E8400u}, // en-SS -> en-001
+    {0x656E5358u, 0x656E8400u}, // en-SX -> en-001
+    {0x656E535Au, 0x656E8400u}, // en-SZ -> en-001
+    {0x656E5443u, 0x656E8400u}, // en-TC -> en-001
+    {0x656E544Bu, 0x656E8400u}, // en-TK -> en-001
+    {0x656E544Fu, 0x656E8400u}, // en-TO -> en-001
+    {0x656E5454u, 0x656E8400u}, // en-TT -> en-001
+    {0x656E5456u, 0x656E8400u}, // en-TV -> en-001
+    {0x656E545Au, 0x656E8400u}, // en-TZ -> en-001
+    {0x656E5547u, 0x656E8400u}, // en-UG -> en-001
+    {0x656E5643u, 0x656E8400u}, // en-VC -> en-001
+    {0x656E5647u, 0x656E8400u}, // en-VG -> en-001
+    {0x656E5655u, 0x656E8400u}, // en-VU -> en-001
+    {0x656E5753u, 0x656E8400u}, // en-WS -> en-001
+    {0x656E5A41u, 0x656E8400u}, // en-ZA -> en-001
+    {0x656E5A4Du, 0x656E8400u}, // en-ZM -> en-001
+    {0x656E5A57u, 0x656E8400u}, // en-ZW -> en-001
+    {0x65734152u, 0x6573A424u}, // es-AR -> es-419
+    {0x6573424Fu, 0x6573A424u}, // es-BO -> es-419
+    {0x6573434Cu, 0x6573A424u}, // es-CL -> es-419
+    {0x6573434Fu, 0x6573A424u}, // es-CO -> es-419
+    {0x65734352u, 0x6573A424u}, // es-CR -> es-419
+    {0x65734355u, 0x6573A424u}, // es-CU -> es-419
+    {0x6573444Fu, 0x6573A424u}, // es-DO -> es-419
+    {0x65734543u, 0x6573A424u}, // es-EC -> es-419
+    {0x65734754u, 0x6573A424u}, // es-GT -> es-419
+    {0x6573484Eu, 0x6573A424u}, // es-HN -> es-419
+    {0x65734D58u, 0x6573A424u}, // es-MX -> es-419
+    {0x65734E49u, 0x6573A424u}, // es-NI -> es-419
+    {0x65735041u, 0x6573A424u}, // es-PA -> es-419
+    {0x65735045u, 0x6573A424u}, // es-PE -> es-419
+    {0x65735052u, 0x6573A424u}, // es-PR -> es-419
+    {0x65735059u, 0x6573A424u}, // es-PY -> es-419
+    {0x65735356u, 0x6573A424u}, // es-SV -> es-419
+    {0x65735553u, 0x6573A424u}, // es-US -> es-419
+    {0x65735559u, 0x6573A424u}, // es-UY -> es-419
+    {0x65735645u, 0x6573A424u}, // es-VE -> es-419
+    {0x7074414Fu, 0x70745054u}, // pt-AO -> pt-PT
+    {0x70744356u, 0x70745054u}, // pt-CV -> pt-PT
+    {0x70744757u, 0x70745054u}, // pt-GW -> pt-PT
+    {0x70744D4Fu, 0x70745054u}, // pt-MO -> pt-PT
+    {0x70744D5Au, 0x70745054u}, // pt-MZ -> pt-PT
+    {0x70745354u, 0x70745054u}, // pt-ST -> pt-PT
+    {0x7074544Cu, 0x70745054u}, // pt-TL -> pt-PT
+});
+
+const struct {
+    const char script[4];
+    const std::unordered_map<uint32_t, uint32_t>* map;
+} SCRIPT_PARENTS[] = {
+    {{'A', 'r', 'a', 'b'}, &ARAB_PARENTS},
+    {{'H', 'a', 'n', 't'}, &HANT_PARENTS},
+    {{'L', 'a', 't', 'n'}, &LATN_PARENTS},
+};
+
+const size_t MAX_PARENT_DEPTH = 3;
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 44f92c7..71e9c92 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -1868,7 +1868,10 @@
     }
 
     // The language & region are equal, so compare the scripts and variants.
-    int script = memcmp(l.localeScript, r.localeScript, sizeof(l.localeScript));
+    const char emptyScript[sizeof(l.localeScript)] = {'\0', '\0', '\0', '\0'};
+    const char *lScript = l.localeScriptWasProvided ? l.localeScript : emptyScript;
+    const char *rScript = r.localeScriptWasProvided ? r.localeScript : emptyScript;
+    int script = memcmp(lScript, rScript, sizeof(l.localeScript));
     if (script) {
         return script;
     }
@@ -2012,10 +2015,10 @@
     // scripts since it seems more useful to do so. We will consider
     // "en-US-POSIX" to be more specific than "en-Latn-US".
 
-    const int score = ((localeScript[0] != 0) ? 1 : 0) +
+    const int score = (localeScriptWasProvided ? 1 : 0) +
         ((localeVariant[0] != 0) ? 2 : 0);
 
-    const int oScore = ((o.localeScript[0] != 0) ? 1 : 0) +
+    const int oScore = (o.localeScriptWasProvided ? 1 : 0) +
         ((o.localeVariant[0] != 0) ? 2 : 0);
 
     return score - oScore;
@@ -2165,6 +2168,63 @@
     return false;
 }
 
+bool ResTable_config::isLocaleBetterThan(const ResTable_config& o,
+        const ResTable_config* requested) const {
+    if (requested->locale == 0) {
+        // The request doesn't have a locale, so no resource is better
+        // than the other.
+        return false;
+    }
+
+    if (locale == 0 && o.locale == 0) {
+        // The locales parts of both resources are empty, so no one is better
+        // than the other.
+        return false;
+    }
+
+    // Non-matching locales have been filtered out, so both resources
+    // match the requested locale.
+    //
+    // Because of the locale-related checks in match() and the checks, we know
+    // that:
+    // 1) The resource languages are either empty or match the request;
+    // and
+    // 2) If the request's script is known, the resource scripts are either
+    //    unknown or match the request.
+
+    if (language[0] != o.language[0]) {
+        // The languages of the two resources are not the same. We can only
+        // assume that one of the two resources matched the request because one
+        // doesn't have a language and the other has a matching language.
+        return (language[0] != 0);
+    }
+
+    // If we are here, both the resources have the same non-empty language as
+    // the request.
+    //
+    // Because the languages are the same, computeScript() always
+    // returns a non-empty script for languages it knows about, and we have passed
+    // the script checks in match(), the scripts are either all unknown or are
+    // all the same. So we can't gain anything by checking the scripts. We need
+    // to check the region and variant.
+
+    // See if any of the regions is better than the other
+    const int region_comparison = localeDataCompareRegions(
+            country, o.country,
+            language, localeScript, requested->country);
+    if (region_comparison != 0) {
+        return (region_comparison > 0);
+    }
+
+    // The regions are the same. Try the variant.
+    if (requested->localeVariant[0] != '\0'
+            && strncmp(localeVariant, requested->localeVariant, sizeof(localeVariant)) == 0) {
+        return (strncmp(o.localeVariant, requested->localeVariant, sizeof(localeVariant)) != 0);
+    }
+
+    return false;
+}
+
 bool ResTable_config::isBetterThan(const ResTable_config& o,
         const ResTable_config* requested) const {
     if (requested) {
@@ -2178,26 +2238,8 @@
             }
         }
 
-        if (locale || o.locale) {
-            if ((language[0] != o.language[0]) && requested->language[0]) {
-                return (language[0]);
-            }
-
-            if ((country[0] != o.country[0]) && requested->country[0]) {
-                return (country[0]);
-            }
-        }
-
-        if (localeScript[0] || o.localeScript[0]) {
-            if (localeScript[0] != o.localeScript[0] && requested->localeScript[0]) {
-                return localeScript[0];
-            }
-        }
-
-        if (localeVariant[0] || o.localeVariant[0]) {
-            if (localeVariant[0] != o.localeVariant[0] && requested->localeVariant[0]) {
-                return localeVariant[0];
-            }
+        if (isLocaleBetterThan(o, requested)) {
+            return true;
         }
 
         if (screenLayout || o.screenLayout) {
@@ -2445,20 +2487,33 @@
         }
     }
     if (locale != 0) {
-        // Don't consider the script & variants when deciding matches.
+        // Don't consider country and variants when deciding matches.
+        // (Theoretically, the variant can also affect the script. For
+        // example, "ar-alalc97" probably implies the Latin script, but since
+        // CLDR doesn't support getting likely scripts for that, we'll assume
+        // the variant doesn't change the script.)
         //
-        // If we two configs differ only in their script or language, they
-        // can be weeded out in the isMoreSpecificThan test.
-        if (language[0] != 0
-            && (language[0] != settings.language[0]
-                || language[1] != settings.language[1])) {
+        // If two configs differ only in their country and variant,
+        // they can be weeded out in the isMoreSpecificThan test.
+        if (language[0] != settings.language[0] || language[1] != settings.language[1]) {
             return false;
         }
 
-        if (country[0] != 0
-            && (country[0] != settings.country[0]
-                || country[1] != settings.country[1])) {
-            return false;
+        // For backward compatibility and supporting private-use locales, we
+        // fall back to old behavior if we couldn't determine the script for
+        // either of the desired locale or the provided locale.
+        if (localeScript[0] == '\0' || localeScript[1] == '\0') {
+            if (country[0] != '\0'
+                && (country[0] != settings.country[0]
+                    || country[1] != settings.country[1])) {
+                return false;
+            }
+        } else {
+            // But if we could determine the scripts, they should be the same
+            // for the locales to match.
+            if (memcmp(localeScript, settings.localeScript, sizeof(localeScript)) != 0) {
+                return false;
+            }
         }
     }
 
@@ -2587,7 +2642,7 @@
         return;
     }
 
-    if (!localeScript[0] && !localeVariant[0]) {
+    if (!localeScriptWasProvided && !localeVariant[0]) {
         // Legacy format.
         if (out.size() > 0) {
             out.append("-");
@@ -2605,7 +2660,7 @@
         return;
     }
 
-    // We are writing the modified bcp47 tag.
+    // We are writing the modified BCP 47 tag.
     // It starts with 'b+' and uses '+' as a separator.
 
     if (out.size() > 0) {
@@ -2617,7 +2672,7 @@
     size_t len = unpackLanguage(buf);
     out.append(buf, len);
 
-    if (localeScript[0]) {
+    if (localeScriptWasProvided) {
         out.append("+");
         out.append(localeScript, sizeof(localeScript));
     }
@@ -2630,7 +2685,7 @@
 
     if (localeVariant[0]) {
         out.append("+");
-        out.append(localeVariant, sizeof(localeVariant));
+        out.append(localeVariant, strnlen(localeVariant, sizeof(localeVariant)));
     }
 }
 
@@ -2648,7 +2703,7 @@
         charsWritten += unpackLanguage(str);
     }
 
-    if (localeScript[0]) {
+    if (localeScriptWasProvided) {
         if (charsWritten) {
             str[charsWritten++] = '-';
         }
@@ -2682,11 +2737,16 @@
            config->language[0] ? config->packRegion(start) : config->packLanguage(start);
            break;
        case 4:
-           config->localeScript[0] = toupper(start[0]);
-           for (size_t i = 1; i < 4; ++i) {
-               config->localeScript[i] = tolower(start[i]);
+           if ('0' <= start[0] && start[0] <= '9') {
+               // this is a variant, so fall through
+           } else {
+               config->localeScript[0] = toupper(start[0]);
+               for (size_t i = 1; i < 4; ++i) {
+                   config->localeScript[i] = tolower(start[i]);
+               }
+               config->localeScriptWasProvided = true;
+               break;
            }
-           break;
        case 5:
        case 6:
        case 7:
@@ -2704,6 +2764,7 @@
 
 void ResTable_config::setBcp47Locale(const char* in) {
     locale = 0;
+    localeScriptWasProvided = false;
     memset(localeScript, 0, sizeof(localeScript));
     memset(localeVariant, 0, sizeof(localeVariant));
 
@@ -2720,6 +2781,9 @@
 
     const size_t size = in + strlen(in) - start;
     assignLocaleComponent(this, start, size);
+    if (localeScript[0] == '\0') {
+        computeScript();
+    };
 }
 
 String8 ResTable_config::toString() const {
diff --git a/libs/androidfw/tests/ConfigLocale_test.cpp b/libs/androidfw/tests/ConfigLocale_test.cpp
index 4999594..1941563 100644
--- a/libs/androidfw/tests/ConfigLocale_test.cpp
+++ b/libs/androidfw/tests/ConfigLocale_test.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <androidfw/LocaleData.h>
 #include <androidfw/ResourceTypes.h>
 #include <utils/Log.h>
 #include <utils/String8.h>
@@ -28,7 +29,7 @@
      EXPECT_EQ('e', config.language[0]);
      EXPECT_EQ('n', config.language[1]);
 
-     char out[4] = { 1, 1, 1, 1};
+     char out[4] = {1, 1, 1, 1};
      config.unpackLanguage(out);
      EXPECT_EQ('e', out[0]);
      EXPECT_EQ('n', out[1]);
@@ -51,7 +52,7 @@
      EXPECT_EQ('U', config.country[0]);
      EXPECT_EQ('S', config.country[1]);
 
-     char out[4] = { 1, 1, 1, 1};
+     char out[4] = {1, 1, 1, 1};
      config.unpackRegion(out);
      EXPECT_EQ('U', out[0]);
      EXPECT_EQ('S', out[1]);
@@ -67,7 +68,7 @@
      EXPECT_EQ('\x99', config.language[0]);
      EXPECT_EQ('\xA4', config.language[1]);
 
-     char out[4] = { 1, 1, 1, 1};
+     char out[4] = {1, 1, 1, 1};
      config.unpackLanguage(out);
      EXPECT_EQ('e', out[0]);
      EXPECT_EQ('n', out[1]);
@@ -91,7 +92,7 @@
      EXPECT_EQ(char(0xbc), config.language[0]);
      EXPECT_EQ(char(0xd3), config.language[1]);
 
-     char out[4] = { 1, 1, 1, 1};
+     char out[4] = {1, 1, 1, 1};
      config.unpackLanguage(out);
      EXPECT_EQ('t', out[0]);
      EXPECT_EQ('g', out[1]);
@@ -103,7 +104,7 @@
      ResTable_config config;
      config.packRegion("419");
 
-     char out[4] = { 1, 1, 1, 1};
+     char out[4] = {1, 1, 1, 1};
      config.unpackRegion(out);
 
      EXPECT_EQ('4', out[0]);
@@ -124,6 +125,10 @@
 
      if (script != NULL) {
          memcpy(out->localeScript, script, 4);
+         out->localeScriptWasProvided = true;
+     } else {
+         out->computeScript();
+         out->localeScriptWasProvided = false;
      }
 
      if (variant != NULL) {
@@ -177,11 +182,12 @@
     EXPECT_EQ('n', test.language[1]);
     EXPECT_EQ('U', test.country[0]);
     EXPECT_EQ('S', test.country[1]);
-    EXPECT_EQ(0, test.localeScript[0]);
+    EXPECT_FALSE(test.localeScriptWasProvided);
+    EXPECT_EQ(0, memcmp("Latn", test.localeScript, 4));
     EXPECT_EQ(0, test.localeVariant[0]);
 
     test.setBcp47Locale("eng-419");
-    char out[4] = { 1, 1, 1, 1};
+    char out[4] = {1, 1, 1, 1};
     test.unpackLanguage(out);
     EXPECT_EQ('e', out[0]);
     EXPECT_EQ('n', out[1]);
@@ -193,17 +199,397 @@
     EXPECT_EQ('1', out[1]);
     EXPECT_EQ('9', out[2]);
 
-
     test.setBcp47Locale("en-Latn-419");
-    memset(out, 1, 4);
     EXPECT_EQ('e', test.language[0]);
     EXPECT_EQ('n', test.language[1]);
-
     EXPECT_EQ(0, memcmp("Latn", test.localeScript, 4));
+    EXPECT_TRUE(test.localeScriptWasProvided);
+    memset(out, 1, 4);
     test.unpackRegion(out);
     EXPECT_EQ('4', out[0]);
     EXPECT_EQ('1', out[1]);
     EXPECT_EQ('9', out[2]);
+
+    test.setBcp47Locale("de-1901");
+    memset(out, 1, 4);
+    test.unpackLanguage(out);
+    EXPECT_EQ('d', out[0]);
+    EXPECT_EQ('e', out[1]);
+    EXPECT_EQ('\0', out[2]);
+    EXPECT_FALSE(test.localeScriptWasProvided);
+    EXPECT_EQ(0, memcmp("Latn", test.localeScript, 4));
+    memset(out, 1, 4);
+    test.unpackRegion(out);
+    EXPECT_EQ('\0', out[0]);
+    EXPECT_EQ(0, strcmp("1901", test.localeVariant));
+
+    test.setBcp47Locale("de-Latn-1901");
+    memset(out, 1, 4);
+    test.unpackLanguage(out);
+    EXPECT_EQ('d', out[0]);
+    EXPECT_EQ('e', out[1]);
+    EXPECT_EQ('\0', out[2]);
+    EXPECT_TRUE(test.localeScriptWasProvided);
+    EXPECT_EQ(0, memcmp("Latn", test.localeScript, 4));
+    memset(out, 1, 4);
+    test.unpackRegion(out);
+    EXPECT_EQ('\0', out[0]);
+    EXPECT_EQ(0, strcmp("1901", test.localeVariant));
 }
 
-}  // namespace android.
+TEST(ConfigLocaleTest, computeScript) {
+    ResTable_config config;
+
+    fillIn(NULL, NULL, NULL, NULL, &config);
+    EXPECT_EQ(0, memcmp("\0\0\0\0", config.localeScript, 4));
+
+    fillIn("zh", "TW", NULL, NULL, &config);
+    EXPECT_EQ(0, memcmp("Hant", config.localeScript, 4));
+
+    fillIn("zh", "CN", NULL, NULL, &config);
+    EXPECT_EQ(0, memcmp("Hans", config.localeScript, 4));
+
+    fillIn("az", NULL, NULL, NULL, &config);
+    EXPECT_EQ(0, memcmp("Latn", config.localeScript, 4));
+
+    fillIn("az", "AZ", NULL, NULL, &config);
+    EXPECT_EQ(0, memcmp("Latn", config.localeScript, 4));
+
+    fillIn("az", "IR", NULL, NULL, &config);
+    EXPECT_EQ(0, memcmp("Arab", config.localeScript, 4));
+
+    fillIn("peo", NULL, NULL, NULL, &config);
+    EXPECT_EQ(0, memcmp("Xpeo", config.localeScript, 4));
+
+    fillIn("qaa", NULL, NULL, NULL, &config);
+    EXPECT_EQ(0, memcmp("\0\0\0\0", config.localeScript, 4));
+}
+
+TEST(ConfigLocaleTest, getBcp47Locale_script) {
+    ResTable_config config;
+    fillIn("en", NULL, "Latn", NULL, &config);
+
+    char out[RESTABLE_MAX_LOCALE_LEN];
+    config.localeScriptWasProvided = true;
+    config.getBcp47Locale(out);
+    EXPECT_EQ(0, strcmp("en-Latn", out));
+
+    config.localeScriptWasProvided = false;
+    config.getBcp47Locale(out);
+    EXPECT_EQ(0, strcmp("en", out));
+}
+
+TEST(ConfigLocaleTest, match) {
+    ResTable_config supported, requested;
+
+    fillIn(NULL, NULL, NULL, NULL, &supported);
+    fillIn("fr", "CA", NULL, NULL, &requested);
+    // Empty locale matches everything (as a default).
+    EXPECT_TRUE(supported.match(requested));
+
+    fillIn("en", "CA", NULL, NULL, &supported);
+    fillIn("fr", "CA", NULL, NULL, &requested);
+    // Different languages don't match.
+    EXPECT_FALSE(supported.match(requested));
+
+    fillIn("qaa", "FR", NULL, NULL, &supported);
+    fillIn("qaa", "CA", NULL, NULL, &requested);
+    // If we can't infer the scripts, different regions don't match.
+    EXPECT_FALSE(supported.match(requested));
+
+    fillIn("qaa", "FR", "Latn", NULL, &supported);
+    fillIn("qaa", "CA", NULL, NULL, &requested);
+    // If we can't infer any of the scripts, different regions don't match.
+    EXPECT_FALSE(supported.match(requested));
+
+    fillIn("qaa", "FR", NULL, NULL, &supported);
+    fillIn("qaa", "CA", "Latn", NULL, &requested);
+    // If we can't infer any of the scripts, different regions don't match.
+    EXPECT_FALSE(supported.match(requested));
+
+    fillIn("qaa", NULL, NULL, NULL, &supported);
+    fillIn("qaa", "CA", NULL, NULL, &requested);
+    // language-only resources still support language+region requests, even if we can't infer the
+    // script.
+    EXPECT_TRUE(supported.match(requested));
+
+    fillIn("qaa", "CA", NULL, NULL, &supported);
+    fillIn("qaa", "CA", NULL, NULL, &requested);
+    // Even if we can't infer the scripts, exactly equal locales match.
+    EXPECT_TRUE(supported.match(requested));
+
+    fillIn("az", NULL, NULL, NULL, &supported);
+    fillIn("az", NULL, "Latn", NULL, &requested);
+    // If the resolved scripts are the same, it doesn't matter if they were explicitly provided
+    // or not, and they match.
+    EXPECT_TRUE(supported.match(requested));
+
+    fillIn("az", NULL, NULL, NULL, &supported);
+    fillIn("az", NULL, "Cyrl", NULL, &requested);
+    // If the resolved scripts are different, they don't match.
+    EXPECT_FALSE(supported.match(requested));
+
+    fillIn("az", NULL, NULL, NULL, &supported);
+    fillIn("az", "IR", NULL, NULL, &requested);
+    // If the resolved scripts are different, they don't match.
+    EXPECT_FALSE(supported.match(requested));
+
+    fillIn("az", "IR", NULL, NULL, &supported);
+    fillIn("az", NULL, "Arab", NULL, &requested);
+    // If the resolved scripts are the same, it doesn't matter if they were explicitly provided
+    // or not, and they match.
+    EXPECT_TRUE(supported.match(requested));
+
+    fillIn("en", NULL, NULL, NULL, &supported);
+    fillIn("en", "XA", NULL, NULL, &requested);
+    // en-XA is a pseudo-locale, and English resources are not a match for it.
+    EXPECT_FALSE(supported.match(requested));
+
+    fillIn("en", "XA", NULL, NULL, &supported);
+    fillIn("en", NULL, NULL, NULL, &requested);
+    // en-XA is a pseudo-locale, and its resources don't support English locales.
+    EXPECT_FALSE(supported.match(requested));
+
+    fillIn("en", "XA", NULL, NULL, &supported);
+    fillIn("en", "XA", NULL, NULL, &requested);
+    // Even if they are pseudo-locales, exactly equal locales match.
+    EXPECT_TRUE(supported.match(requested));
+
+    fillIn("ar", NULL, NULL, NULL, &supported);
+    fillIn("ar", "XB", NULL, NULL, &requested);
+    // ar-XB is a pseudo-locale, and Arabic resources are not a match for it.
+    EXPECT_FALSE(supported.match(requested));
+
+    fillIn("ar", "XB", NULL, NULL, &supported);
+    fillIn("ar", NULL, NULL, NULL, &requested);
+    // ar-XB is a pseudo-locale, and its resources don't support Arabic locales.
+    EXPECT_FALSE(supported.match(requested));
+
+    fillIn("ar", "XB", NULL, NULL, &supported);
+    fillIn("ar", "XB", NULL, NULL, &requested);
+    // Even if they are pseudo-locales, exactly equal locales match.
+    EXPECT_TRUE(supported.match(requested));
+}
+
+TEST(ConfigLocaleTest, isLocaleBetterThan_basics) {
+    ResTable_config config1, config2, request;
+
+    fillIn(NULL, NULL, NULL, NULL, &request);
+    fillIn("fr", "FR", NULL, NULL, &config1);
+    fillIn("fr", "CA", NULL, NULL, &config2);
+    EXPECT_FALSE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("fr", "CA", NULL, NULL, &request);
+    fillIn(NULL, NULL, NULL, NULL, &config1);
+    fillIn(NULL, NULL, NULL, NULL, &config2);
+    EXPECT_FALSE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("fr", "CA", NULL, NULL, &request);
+    fillIn("fr", "FR", NULL, NULL, &config1);
+    fillIn(NULL, NULL, NULL, NULL, &config2);
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("de", "DE", NULL, NULL, &request);
+    fillIn("de", "DE", NULL, "1901", &config1);
+    fillIn("de", "DE", NULL, "1996", &config2);
+    EXPECT_FALSE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("de", "DE", NULL, "1901", &request);
+    fillIn("de", "DE", NULL, "1901", &config1);
+    fillIn("de", "DE", NULL, NULL, &config2);
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("de", "DE", NULL, "1901", &request);
+    fillIn("de", "DE", NULL, "1996", &config1);
+    fillIn("de", "DE", NULL, NULL, &config2);
+    EXPECT_FALSE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+}
+
+TEST(ConfigLocaleTest, isLocaleBetterThan_regionComparison) {
+    ResTable_config config1, config2, request;
+
+    fillIn("es", "AR", NULL, NULL, &request);
+    fillIn("es", "419", NULL, NULL, &config1);
+    fillIn("es", "419", NULL, NULL, &config2);
+    // Both supported locales are the same, so none is better than the other.
+    EXPECT_FALSE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("es", "AR", NULL, NULL, &request);
+    fillIn("es", "AR", NULL, NULL, &config1);
+    fillIn("es", "419", NULL, NULL, &config2);
+    // An exact locale match is better than a parent.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("es", "AR", NULL, NULL, &request);
+    fillIn("es", "419", NULL, NULL, &config1);
+    fillIn("es", NULL, NULL, NULL, &config2);
+    // A closer parent is better.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("es", "AR", NULL, NULL, &request);
+    fillIn("es", "419", NULL, NULL, &config1);
+    fillIn("es", "ES", NULL, NULL, &config2);
+    // A parent is better than a non-parent representative locale.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("es", "AR", NULL, NULL, &request);
+    fillIn("es", NULL, NULL, NULL, &config1);
+    fillIn("es", "ES", NULL, NULL, &config2);
+    // A parent is better than a non-parent representative locale.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("es", "AR", NULL, NULL, &request);
+    fillIn("es", "PE", NULL, NULL, &config1);
+    fillIn("es", "ES", NULL, NULL, &config2);
+    // A closer locale is better.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("es", "AR", NULL, NULL, &request);
+    fillIn("es", "MX", NULL, NULL, &config1);
+    fillIn("es", "BO", NULL, NULL, &config2);
+    // A representative locale is better if they are equidistant.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("es", "AR", NULL, NULL, &request);
+    fillIn("es", "US", NULL, NULL, &config1);
+    fillIn("es", "BO", NULL, NULL, &config2);
+    // A representative locale is better if they are equidistant.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("es", "AR", NULL, NULL, &request);
+    fillIn("es", "MX", NULL, NULL, &config1);
+    fillIn("es", "US", NULL, NULL, &config2);
+    // If all is equal, the locale earlier in the dictionary is better.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("es", "GQ", NULL, NULL, &request);
+    fillIn("es", "IC", NULL, NULL, &config1);
+    fillIn("es", "419", NULL, NULL, &config2);
+    // If all is equal, the locale earlier in the dictionary is better and
+    // letters are better than numbers.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("en", "GB", NULL, NULL, &request);
+    fillIn("en", "001", NULL, NULL, &config1);
+    fillIn("en", NULL, NULL, NULL, &config2);
+    // A closer parent is better.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("en", "PR", NULL, NULL, &request);
+    fillIn("en", NULL, NULL, NULL, &config1);
+    fillIn("en", "001", NULL, NULL, &config2);
+    // A parent is better than a non-parent.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("en", "DE", NULL, NULL, &request);
+    fillIn("en", "150", NULL, NULL, &config1);
+    fillIn("en", "001", NULL, NULL, &config2);
+    // A closer parent is better.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("en", "IN", NULL, NULL, &request);
+    fillIn("en", "AU", NULL, NULL, &config1);
+    fillIn("en", "US", NULL, NULL, &config2);
+    // A closer locale is better.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("en", "PR", NULL, NULL, &request);
+    fillIn("en", "001", NULL, NULL, &config1);
+    fillIn("en", "GB", NULL, NULL, &config2);
+    // A closer locale is better.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("en", "IN", NULL, NULL, &request);
+    fillIn("en", "GB", NULL, NULL, &config1);
+    fillIn("en", "AU", NULL, NULL, &config2);
+    // A representative locale is better if they are equidistant.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("en", "IN", NULL, NULL, &request);
+    fillIn("en", "AU", NULL, NULL, &config1);
+    fillIn("en", "CA", NULL, NULL, &config2);
+    // If all is equal, the locale earlier in the dictionary is better.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("pt", "MZ", NULL, NULL, &request);
+    fillIn("pt", "PT", NULL, NULL, &config1);
+    fillIn("pt", NULL, NULL, NULL, &config2);
+    // A closer parent is better.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("pt", "MZ", NULL, NULL, &request);
+    fillIn("pt", "PT", NULL, NULL, &config1);
+    fillIn("pt", "BR", NULL, NULL, &config2);
+    // A parent is better than a non-parent.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("zh", "MO", "Hant", NULL, &request);
+    fillIn("zh", "HK", "Hant", NULL, &config1);
+    fillIn("zh", "TW", "Hant", NULL, &config2);
+    // A parent is better than a non-parent.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("zh", "US", "Hant", NULL, &request);
+    fillIn("zh", "TW", "Hant", NULL, &config1);
+    fillIn("zh", "HK", "Hant", NULL, &config2);
+    // A representative locale is better if they are equidistant.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("ar", "DZ", NULL, NULL, &request);
+    fillIn("ar", "015", NULL, NULL, &config1);
+    fillIn("ar", NULL, NULL, NULL, &config2);
+    // A closer parent is better.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("ar", "EG", NULL, NULL, &request);
+    fillIn("ar", NULL, NULL, NULL, &config1);
+    fillIn("ar", "015", NULL, NULL, &config2);
+    // A parent is better than a non-parent.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("ar", "QA", NULL, NULL, &request);
+    fillIn("ar", "EG", NULL, NULL, &config1);
+    fillIn("ar", "BH", NULL, NULL, &config2);
+    // A representative locale is better if they are equidistant.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+
+    fillIn("ar", "QA", NULL, NULL, &request);
+    fillIn("ar", "SA", NULL, NULL, &config1);
+    fillIn("ar", "015", NULL, NULL, &config2);
+    // If all is equal, the locale earlier in the dictionary is better and
+    // letters are better than numbers.
+    EXPECT_TRUE(config1.isLocaleBetterThan(config2, &request));
+    EXPECT_FALSE(config2.isLocaleBetterThan(config1, &request));
+}
+
+}  // namespace android
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 1248a4c..8ba6318 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -2,7 +2,7 @@
 include $(CLEAR_VARS)
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
-HWUI_NEW_OPS := false
+HWUI_NEW_OPS := true
 
 hwui_src_files := \
     font/CacheTexture.cpp \
diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp
index 0931282..e65746e 100644
--- a/libs/hwui/BakedOpRenderer.cpp
+++ b/libs/hwui/BakedOpRenderer.cpp
@@ -139,9 +139,7 @@
     mCaches.pathCache.trim();
     mCaches.tessellationCache.trim();
 
-#if DEBUG_OPENGL
-    GLUtils::dumpGLErrors();
-#endif
+    GL_CHECKPOINT();
 
 #if DEBUG_MEMORY_USAGE
     mCaches.dumpMemoryUsage();
diff --git a/libs/hwui/Dither.cpp b/libs/hwui/Dither.cpp
index 1ba6511..ec2013e 100644
--- a/libs/hwui/Dither.cpp
+++ b/libs/hwui/Dither.cpp
@@ -54,7 +54,6 @@
                 15 * dither,  7 * dither, 13 * dither,  5 * dither
             };
 
-            glPixelStorei(GL_UNPACK_ALIGNMENT, sizeof(GLfloat));
             glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, DITHER_KERNEL_SIZE, DITHER_KERNEL_SIZE, 0,
                     GL_RED, GL_FLOAT, &pattern);
         } else {
@@ -65,7 +64,6 @@
                 15,  7, 13,  5
             };
 
-            glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
             glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, DITHER_KERNEL_SIZE, DITHER_KERNEL_SIZE, 0,
                     GL_ALPHA, GL_UNSIGNED_BYTE, &pattern);
         }
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index ed31a2c..68bae6d 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -458,7 +458,6 @@
     GLuint lastTextureId = 0;
 
     bool resetPixelStore = false;
-    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
     // Iterate over all the cache textures and see which ones need to be updated
     checkTextureUpdateForCache(caches, mACacheTextures, resetPixelStore, lastTextureId);
diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp
index 1473bc8..e899ac7 100644
--- a/libs/hwui/GradientCache.cpp
+++ b/libs/hwui/GradientCache.cpp
@@ -273,8 +273,6 @@
 
     memcpy(pixels + rowBytes, pixels, rowBytes);
 
-    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-
     if (mUseFloatTexture) {
         // We have to use GL_RGBA16F because GL_RGBA32F does not support filtering
         texture->upload(GL_RGBA16F, width, height, GL_RGBA, GL_FLOAT, pixels);
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 8369266..114347d 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -207,7 +207,6 @@
 #endif
     if (texture.mId) {
         texture.updateSize(getWidth(), getHeight(), GL_RGBA);
-        glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
         glTexImage2D(renderTarget, 0, GL_RGBA, getWidth(), getHeight(), 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
     }
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 0cf643f..0f219e4 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -373,7 +373,6 @@
         GLenum format;
         GLenum type;
 
-        GLenum error = GL_NO_ERROR;
         bool status = false;
 
         switch (bitmap->colorType()) {
@@ -408,7 +407,7 @@
         renderState.bindFramebuffer(fbo);
 
         glGenTextures(1, &texture);
-        if ((error = glGetError()) != GL_NO_ERROR) goto error;
+        GL_CHECKPOINT();
 
         caches.textureState().activateTexture(0);
         caches.textureState().bindTexture(texture);
@@ -423,11 +422,11 @@
 
         glTexImage2D(GL_TEXTURE_2D, 0, format, bitmap->width(), bitmap->height(),
                 0, format, type, nullptr);
-        if ((error = glGetError()) != GL_NO_ERROR) goto error;
+        GL_CHECKPOINT();
 
         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                 GL_TEXTURE_2D, texture, 0);
-        if ((error = glGetError()) != GL_NO_ERROR) goto error;
+        GL_CHECKPOINT();
 
         {
             LayerRenderer renderer(renderState, layer);
@@ -438,7 +437,7 @@
             renderer.translate(0.0f, bitmap->height());
             renderer.scale(1.0f, -1.0f);
 
-            if ((error = glGetError()) != GL_NO_ERROR) goto error;
+            GL_CHECKPOINT();
 
             {
                 Rect bounds;
@@ -448,19 +447,12 @@
                 glReadPixels(0, 0, bitmap->width(), bitmap->height(), format,
                         type, bitmap->getPixels());
 
-                if ((error = glGetError()) != GL_NO_ERROR) goto error;
+                GL_CHECKPOINT();
             }
 
             status = true;
         }
 
-error:
-#if DEBUG_OPENGL
-        if (error != GL_NO_ERROR) {
-            ALOGD("GL error while copying layer into bitmap = 0x%x", error);
-        }
-#endif
-
         renderState.bindFramebuffer(previousFbo);
         layer->setAlpha(alpha, mode);
         layer->setFbo(previousLayerFbo);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 0cd763d..1bfa308 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -195,9 +195,7 @@
     }
 
     if (!suppressErrorChecks()) {
-#if DEBUG_OPENGL
-        GLUtils::dumpGLErrors();
-#endif
+        GL_CHECKPOINT();
 
 #if DEBUG_MEMORY_USAGE
         mCaches.dumpMemoryUsage();
diff --git a/libs/hwui/PixelBuffer.cpp b/libs/hwui/PixelBuffer.cpp
index 9624726..6df994c 100644
--- a/libs/hwui/PixelBuffer.cpp
+++ b/libs/hwui/PixelBuffer.cpp
@@ -20,6 +20,7 @@
 #include "Extensions.h"
 #include "Properties.h"
 #include "renderstate/RenderState.h"
+#include "utils/GLUtils.h"
 
 #include <utils/Log.h>
 
@@ -112,14 +113,10 @@
     if (mAccessMode == kAccessMode_None) {
         mCaches.pixelBufferState().bind(mBuffer);
         mMappedPointer = (uint8_t*) glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, getSize(), mode);
-#if DEBUG_OPENGL
-        if (!mMappedPointer) {
-            GLenum status = GL_NO_ERROR;
-            while ((status = glGetError()) != GL_NO_ERROR) {
-                ALOGE("Could not map GPU pixel buffer: 0x%x", status);
-            }
+        if (CC_UNLIKELY(!mMappedPointer)) {
+            GLUtils::dumpGLErrors();
+            LOG_ALWAYS_FATAL("Failed to map PBO");
         }
-#endif
         mAccessMode = mode;
     }
 
diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp
index f1e28b7..62a20fc 100644
--- a/libs/hwui/TextDropShadowCache.cpp
+++ b/libs/hwui/TextDropShadowCache.cpp
@@ -200,8 +200,6 @@
         }
 
         // Textures are Alpha8
-        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
         texture->upload(GL_ALPHA, shadow.width, shadow.height,
                 GL_ALPHA, GL_UNSIGNED_BYTE, shadow.image);
         texture->setFilter(GL_LINEAR);
diff --git a/libs/hwui/Texture.cpp b/libs/hwui/Texture.cpp
index 771d004..c5000e4 100644
--- a/libs/hwui/Texture.cpp
+++ b/libs/hwui/Texture.cpp
@@ -95,34 +95,26 @@
 void Texture::upload(GLint internalformat, uint32_t width, uint32_t height,
         GLenum format, GLenum type, const void* pixels) {
     GL_CHECKPOINT();
-    bool needsAlloc = updateSize(width, height, internalformat);
-    if (!needsAlloc && !pixels) {
-        return;
-    }
     mCaches.textureState().activateTexture(0);
-    GL_CHECKPOINT();
+    bool needsAlloc = updateSize(width, height, internalformat);
     if (!mId) {
         glGenTextures(1, &mId);
         needsAlloc = true;
     }
-    GL_CHECKPOINT();
     mCaches.textureState().bindTexture(GL_TEXTURE_2D, mId);
-    GL_CHECKPOINT();
     if (needsAlloc) {
         glTexImage2D(GL_TEXTURE_2D, 0, mFormat, mWidth, mHeight, 0,
                 format, type, pixels);
-        GL_CHECKPOINT();
-    } else {
+    } else if (pixels) {
         glTexSubImage2D(GL_TEXTURE_2D, 0, mFormat, mWidth, mHeight, 0,
                 format, type, pixels);
-        GL_CHECKPOINT();
     }
+    GL_CHECKPOINT();
 }
 
 static void uploadToTexture(bool resize, GLenum format, GLenum type, GLsizei stride, GLsizei bpp,
         GLsizei width, GLsizei height, const GLvoid * data) {
 
-    glPixelStorei(GL_UNPACK_ALIGNMENT, bpp);
     const bool useStride = stride != width
             && Caches::getInstance().extensions().hasUnpackRowLength();
     if ((stride == width) || useStride) {
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index 793df92..3e20608 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -31,7 +31,7 @@
 
 const int Tree::MAX_CACHED_BITMAP_SIZE = 2048;
 
-void Path::draw(Canvas* outCanvas, const SkMatrix& groupStackedMatrix, float scaleX, float scaleY) {
+void Path::draw(SkCanvas* outCanvas, const SkMatrix& groupStackedMatrix, float scaleX, float scaleY) {
     float matrixScale = getMatrixScale(groupStackedMatrix);
     if (matrixScale == 0) {
         // When either x or y is scaled to 0, we don't need to draw anything.
@@ -186,7 +186,7 @@
     return SkColorSetA(color, alphaBytes * alpha);
 }
 
-void FullPath::drawPath(Canvas* outCanvas, const SkPath& renderPath, float strokeScale){
+void FullPath::drawPath(SkCanvas* outCanvas, const SkPath& renderPath, float strokeScale){
     // Draw path's fill, if fill color isn't transparent.
     if (mFillColor != SK_ColorTRANSPARENT) {
         mPaint.setStyle(SkPaint::Style::kFill_Style);
@@ -287,9 +287,9 @@
     return true;
 }
 
-void ClipPath::drawPath(Canvas* outCanvas, const SkPath& renderPath,
+void ClipPath::drawPath(SkCanvas* outCanvas, const SkPath& renderPath,
         float strokeScale){
-    outCanvas->clipPath(&renderPath, SkRegion::kIntersect_Op);
+    outCanvas->clipPath(renderPath, SkRegion::kIntersect_Op);
 }
 
 Group::Group(const Group& group) : Node(group) {
@@ -302,7 +302,7 @@
     mTranslateY = group.mTranslateY;
 }
 
-void Group::draw(Canvas* outCanvas, const SkMatrix& currentMatrix, float scaleX,
+void Group::draw(SkCanvas* outCanvas, const SkMatrix& currentMatrix, float scaleX,
         float scaleY) {
     // TODO: Try apply the matrix to the canvas instead of passing it down the tree
 
@@ -315,7 +315,7 @@
     stackedMatrix.postConcat(currentMatrix);
 
     // Save the current clip information, which is local to this group.
-    outCanvas->save(SkCanvas::kMatrixClip_SaveFlag);
+    outCanvas->save();
     // Draw the group tree in the same order as the XML file.
     for (Node* child : mChildren) {
         child->draw(outCanvas, stackedMatrix, scaleX, scaleY);
@@ -465,10 +465,10 @@
 
 void Tree::updateCachedBitmap(int width, int height) {
     mCachedBitmap.eraseColor(SK_ColorTRANSPARENT);
-    Canvas* outCanvas = Canvas::create_canvas(mCachedBitmap);
+    SkCanvas outCanvas(mCachedBitmap);
     float scaleX = width / mViewportWidth;
     float scaleY = height / mViewportHeight;
-    mRootNode->draw(outCanvas, SkMatrix::I(), scaleX, scaleY);
+    mRootNode->draw(&outCanvas, SkMatrix::I(), scaleX, scaleY);
     mCacheDirty = false;
 }
 
diff --git a/libs/hwui/VectorDrawable.h b/libs/hwui/VectorDrawable.h
index 6c84b05..5ae5f6a 100644
--- a/libs/hwui/VectorDrawable.h
+++ b/libs/hwui/VectorDrawable.h
@@ -20,6 +20,7 @@
 #include "Canvas.h"
 #include <SkBitmap.h>
 #include <SkColor.h>
+#include <SkCanvas.h>
 #include <SkMatrix.h>
 #include <SkPaint.h>
 #include <SkPath.h>
@@ -56,7 +57,7 @@
         mName = node.mName;
     }
     Node() {}
-    virtual void draw(Canvas* outCanvas, const SkMatrix& currentMatrix,
+    virtual void draw(SkCanvas* outCanvas, const SkMatrix& currentMatrix,
             float scaleX, float scaleY) = 0;
     virtual void dump() = 0;
     void setName(const char* name) {
@@ -85,7 +86,7 @@
     void dump() override;
     bool canMorph(const Data& path);
     bool canMorph(const Path& path);
-    void draw(Canvas* outCanvas, const SkMatrix& groupStackedMatrix,
+    void draw(SkCanvas* outCanvas, const SkMatrix& groupStackedMatrix,
             float scaleX, float scaleY) override;
     void setPath(const char* path, size_t strLength);
     void setPathData(const Data& data);
@@ -93,7 +94,7 @@
 
 protected:
     virtual const SkPath& getUpdatedPath();
-    virtual void drawPath(Canvas *outCanvas, const SkPath& renderPath,
+    virtual void drawPath(SkCanvas *outCanvas, const SkPath& renderPath,
             float strokeScale) = 0;
     Data mData;
     SkPath mSkPath;
@@ -163,7 +164,7 @@
 
 protected:
     const SkPath& getUpdatedPath() override;
-    void drawPath(Canvas* outCanvas, const SkPath& renderPath,
+    void drawPath(SkCanvas* outCanvas, const SkPath& renderPath,
             float strokeScale) override;
 
 private:
@@ -193,7 +194,7 @@
     ClipPath(const Data& nodes) : Path(nodes) {}
 
 protected:
-    void drawPath(Canvas* outCanvas, const SkPath& renderPath,
+    void drawPath(SkCanvas* outCanvas, const SkPath& renderPath,
             float strokeScale) override;
 };
 
@@ -243,7 +244,7 @@
     void setTranslateY(float translateY) {
         mTranslateY = translateY;
     }
-    virtual void draw(Canvas* outCanvas, const SkMatrix& currentMatrix,
+    virtual void draw(SkCanvas* outCanvas, const SkMatrix& currentMatrix,
             float scaleX, float scaleY) override;
     void updateLocalMatrix(float rotate, float pivotX, float pivotY,
             float scaleX, float scaleY, float translateX, float translateY);
diff --git a/libs/hwui/renderstate/TextureState.cpp b/libs/hwui/renderstate/TextureState.cpp
index 26ebdee..78b8eda 100644
--- a/libs/hwui/renderstate/TextureState.cpp
+++ b/libs/hwui/renderstate/TextureState.cpp
@@ -43,6 +43,7 @@
     glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
     LOG_ALWAYS_FATAL_IF(maxTextureUnits < kTextureUnitsCount,
             "At least %d texture units are required!", kTextureUnitsCount);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 }
 
 void TextureState::activateTexture(GLuint textureUnit) {
diff --git a/libs/hwui/utils/GLUtils.h b/libs/hwui/utils/GLUtils.h
index 6c521e4..85a10f9 100644
--- a/libs/hwui/utils/GLUtils.h
+++ b/libs/hwui/utils/GLUtils.h
@@ -16,12 +16,14 @@
 #ifndef GLUTILS_H
 #define GLUTILS_H
 
+#include "Debug.h"
+
 #include <cutils/log.h>
 
 namespace android {
 namespace uirenderer {
 
-#if 0
+#if DEBUG_OPENGL
 #define GL_CHECKPOINT() LOG_ALWAYS_FATAL_IF(GLUtils::dumpGLErrors(),\
         "GL errors! %s:%d", __FILE__, __LINE__)
 #else
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 5ad6b08..dc534be 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -2163,7 +2163,7 @@
      * audio service.
      */
     private final ServiceEventHandlerDelegate mServiceEventHandlerDelegate =
-            new ServiceEventHandlerDelegate();
+            new ServiceEventHandlerDelegate(null);
 
     /**
      * Event types
@@ -2177,10 +2177,14 @@
     private class ServiceEventHandlerDelegate {
         private final Handler mHandler;
 
-        ServiceEventHandlerDelegate() {
+        ServiceEventHandlerDelegate(Handler handler) {
             Looper looper;
-            if ((looper = Looper.myLooper()) == null) {
-                looper = Looper.getMainLooper();
+            if (handler == null) {
+                if ((looper = Looper.myLooper()) == null) {
+                    looper = Looper.getMainLooper();
+                }
+            } else {
+                looper = handler.getLooper();
             }
 
             if (looper != null) {
@@ -2201,27 +2205,9 @@
                                 }
                                 break;
                             case MSSG_RECORDING_CONFIG_CHANGE:
-                                // optimizing for the case of a single callback
-                                AudioRecordingCallback singleCallback = null;
-                                ArrayList<AudioRecordingCallback> multipleCallbacks = null;
-                                synchronized(mRecordCallbackLock) {
-                                    if ((mRecordCallbackList != null)
-                                            && (mRecordCallbackList.size() != 0)) {
-                                        if (mRecordCallbackList.size() == 1) {
-                                            singleCallback = mRecordCallbackList.get(0);
-                                        } else {
-                                            multipleCallbacks =
-                                                    new ArrayList<AudioRecordingCallback>(
-                                                            mRecordCallbackList);
-                                        }
-                                    }
-                                }
-                                if (singleCallback != null) {
-                                    singleCallback.onRecordConfigChanged();
-                                } else if (multipleCallbacks != null) {
-                                    for (int i=0 ; i < multipleCallbacks.size() ; i++) {
-                                        multipleCallbacks.get(i).onRecordConfigChanged();
-                                    }
+                                final AudioRecordingCallback cb = (AudioRecordingCallback) msg.obj;
+                                if (cb != null) {
+                                    cb.onRecordConfigChanged();
                                 }
                                 break;
                             default:
@@ -2798,34 +2784,51 @@
     //====================================================================
     // Recording configuration
     /**
-     * @hide
-     * candidate for public API
+     * Interface for receiving update notifications about the recording configuration. Extend
+     * this abstract class and register it with
+     * {@link AudioManager#registerAudioRecordingCallback(AudioRecordingCallback, Handler)}
+     * to be notified.
+     * Use {@link AudioManager#getActiveRecordConfigurations()} to query the current configuration.
      */
     public static abstract class AudioRecordingCallback {
         /**
-         * @hide
-         * candidate for public API
+         * Called whenever the device recording configuration has changed.
          */
         public void onRecordConfigChanged() {}
     }
 
+    private static class AudioRecordingCallbackInfo {
+        final AudioRecordingCallback mCb;
+        final Handler mHandler;
+        AudioRecordingCallbackInfo(AudioRecordingCallback cb, Handler handler) {
+            mCb = cb;
+            mHandler = handler;
+        }
+    }
+
     /**
-     * @hide
-     * candidate for public API
-     * @param non-null callback
+     * Register a callback to be notified of audio recording changes through
+     * {@link AudioRecordingCallback}
+     * @param cb non-null callback to register
+     * @param handler the {@link Handler} object for the thread on which to execute
+     * the callback. If <code>null</code>, the {@link Handler} associated with the main
+     * {@link Looper} will be used.
      */
-    public void registerAudioRecordingCallback(@NonNull AudioRecordingCallback cb) {
+    public void registerAudioRecordingCallback(@NonNull AudioRecordingCallback cb, Handler handler)
+    {
         if (cb == null) {
             throw new IllegalArgumentException("Illegal null AudioRecordingCallback argument");
         }
+
         synchronized(mRecordCallbackLock) {
             // lazy initialization of the list of recording callbacks
             if (mRecordCallbackList == null) {
-                mRecordCallbackList = new ArrayList<AudioRecordingCallback>();
+                mRecordCallbackList = new ArrayList<AudioRecordingCallbackInfo>();
             }
             final int oldCbCount = mRecordCallbackList.size();
-            if (!mRecordCallbackList.contains(cb)) {
-                mRecordCallbackList.add(cb);
+            if (!hasRecordCallback_sync(cb)) {
+                mRecordCallbackList.add(new AudioRecordingCallbackInfo(cb,
+                        new ServiceEventHandlerDelegate(handler).getHandler()));
                 final int newCbCount = mRecordCallbackList.size();
                 if ((oldCbCount == 0) && (newCbCount > 0)) {
                     // register binder for callbacks
@@ -2844,9 +2847,9 @@
     }
 
     /**
-     * @hide
-     * candidate for public API
-     * @param non-null callback
+     * Unregister an audio recording callback previously registered with
+     * {@link #registerAudioRecordingCallback(AudioRecordingCallback, Handler)}.
+     * @param cb non-null callback to unregister
      */
     public void unregisterAudioRecordingCallback(@NonNull AudioRecordingCallback cb) {
         if (cb == null) {
@@ -2857,7 +2860,7 @@
                 return;
             }
             final int oldCbCount = mRecordCallbackList.size();
-            if (mRecordCallbackList.remove(cb)) {
+            if (removeRecordCallback_sync(cb)) {
                 final int newCbCount = mRecordCallbackList.size();
                 if ((oldCbCount > 0) && (newCbCount == 0)) {
                     // unregister binder for callbacks
@@ -2876,8 +2879,7 @@
     }
 
     /**
-     * @hide
-     * candidate for public API
+     * Returns the current active audio recording configurations of the device.
      * @return a non-null array of recording configurations. An array of length 0 indicates there is
      *     no recording active when queried.
      */
@@ -2902,18 +2904,57 @@
 
     /**
      * All operations on this list are sync'd on mRecordCallbackLock.
-     * List is lazy-initialized in {@link #registerAudioRecordingCallback(AudioRecordingCallback)}.
+     * List is lazy-initialized in
+     * {@link #registerAudioRecordingCallback(AudioRecordingCallback, Handler)}.
      * List can be null.
      */
-    private List<AudioRecordingCallback> mRecordCallbackList;
+    private List<AudioRecordingCallbackInfo> mRecordCallbackList;
     private final Object mRecordCallbackLock = new Object();
 
+    /**
+     * Must be called synchronized on mRecordCallbackLock
+     */
+    private boolean hasRecordCallback_sync(@NonNull AudioRecordingCallback cb) {
+        if (mRecordCallbackList != null) {
+            for (int i=0 ; i < mRecordCallbackList.size() ; i++) {
+                if (cb.equals(mRecordCallbackList.get(i).mCb)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Must be called synchronized on mRecordCallbackLock
+     */
+    private boolean removeRecordCallback_sync(@NonNull AudioRecordingCallback cb) {
+        if (mRecordCallbackList != null) {
+            for (int i=0 ; i < mRecordCallbackList.size() ; i++) {
+                if (cb.equals(mRecordCallbackList.get(i).mCb)) {
+                    mRecordCallbackList.remove(i);
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     private final IRecordingConfigDispatcher mRecCb = new IRecordingConfigDispatcher.Stub() {
 
         public void dispatchRecordingConfigChange() {
-            final Message m = mServiceEventHandlerDelegate.getHandler().obtainMessage(
-                    MSSG_RECORDING_CONFIG_CHANGE/*what*/);
-            mServiceEventHandlerDelegate.getHandler().sendMessage(m);
+            synchronized(mRecordCallbackLock) {
+                if (mRecordCallbackList != null) {
+                    for (int i=0 ; i < mRecordCallbackList.size() ; i++) {
+                        final AudioRecordingCallbackInfo arci = mRecordCallbackList.get(i);
+                        if (arci.mHandler != null) {
+                            final Message m = arci.mHandler.obtainMessage(
+                                    MSSG_RECORDING_CONFIG_CHANGE/*what*/, arci.mCb/*obj*/);
+                            arci.mHandler.sendMessage(m);
+                        }
+                    }
+                }
+            }
         }
 
     };
diff --git a/media/java/android/media/AudioRecordConfiguration.java b/media/java/android/media/AudioRecordConfiguration.java
index aefe692..c7d219d 100644
--- a/media/java/android/media/AudioRecordConfiguration.java
+++ b/media/java/android/media/AudioRecordConfiguration.java
@@ -22,8 +22,9 @@
 import java.util.Objects;
 
 /**
- * @hide
- * Candidate for public API, see AudioManager.getActiveRecordConfiguration()
+ * The AudioRecordConfiguration class collects the information describing an audio recording
+ * session. This information is returned through the 
+ * {@link AudioManager#getActiveRecordConfigurations()} method.
  *
  */
 public class AudioRecordConfiguration implements Parcelable {
@@ -41,19 +42,23 @@
     }
 
     /**
-     * @return one of AudioSource.MIC, AudioSource.VOICE_UPLINK,
-     *       AudioSource.VOICE_DOWNLINK, AudioSource.VOICE_CALL,
-     *       AudioSource.CAMCORDER, AudioSource.VOICE_RECOGNITION,
-     *       AudioSource.VOICE_COMMUNICATION.
+     * Returns the audio source being used for the recording.
+     * @return one of {@link MediaRecorder.AudioSource#MIC},
+     *       {@link MediaRecorder.AudioSource#VOICE_UPLINK},
+     *       {@link MediaRecorder.AudioSource#VOICE_DOWNLINK},
+     *       {@link MediaRecorder.AudioSource#VOICE_CALL},
+     *       {@link MediaRecorder.AudioSource#CAMCORDER},
+     *       {@link MediaRecorder.AudioSource#VOICE_RECOGNITION},
+     *       {@link MediaRecorder.AudioSource#VOICE_COMMUNICATION}.
      */
     public int getClientAudioSource() { return mClientSource; }
 
     /**
-     * @return the session number of the recorder.
+     * Returns the session number of the recording, see {@link AudioRecord#getAudioSessionId()}.
+     * @return the session number.
      */
     public int getAudioSessionId() { return mSessionId; }
 
-
     public static final Parcelable.Creator<AudioRecordConfiguration> CREATOR
             = new Parcelable.Creator<AudioRecordConfiguration>() {
         /**
diff --git a/media/java/android/media/Cea708CaptionRenderer.java b/media/java/android/media/Cea708CaptionRenderer.java
new file mode 100644
index 0000000..88912fe
--- /dev/null
+++ b/media/java/android/media/Cea708CaptionRenderer.java
@@ -0,0 +1,2151 @@
+/*
+ * 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.media;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.Typeface;
+import android.os.Handler;
+import android.os.Message;
+import android.text.SpannableStringBuilder;
+import android.text.Spanned;
+import android.text.style.CharacterStyle;
+import android.text.style.RelativeSizeSpan;
+import android.text.style.StyleSpan;
+import android.text.style.SubscriptSpan;
+import android.text.style.SuperscriptSpan;
+import android.text.style.UnderlineSpan;
+import android.util.AttributeSet;
+import android.text.Layout.Alignment;
+import android.util.Log;
+import android.text.TextUtils;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.CaptioningManager;
+import android.view.accessibility.CaptioningManager.CaptionStyle;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Vector;
+
+import com.android.internal.widget.SubtitleView;
+
+/** @hide */
+public class Cea708CaptionRenderer extends SubtitleController.Renderer {
+    private final Context mContext;
+    private Cea708CCWidget mCCWidget;
+
+    public Cea708CaptionRenderer(Context context) {
+        mContext = context;
+    }
+
+    @Override
+    public boolean supports(MediaFormat format) {
+        if (format.containsKey(MediaFormat.KEY_MIME)) {
+            String mimeType = format.getString(MediaFormat.KEY_MIME);
+            return MediaPlayer.MEDIA_MIMETYPE_TEXT_CEA_708.equals(mimeType);
+        }
+        return false;
+    }
+
+    @Override
+    public SubtitleTrack createTrack(MediaFormat format) {
+        String mimeType = format.getString(MediaFormat.KEY_MIME);
+        if (MediaPlayer.MEDIA_MIMETYPE_TEXT_CEA_708.equals(mimeType)) {
+            if (mCCWidget == null) {
+                mCCWidget = new Cea708CCWidget(mContext);
+            }
+            return new Cea708CaptionTrack(mCCWidget, format);
+        }
+        throw new RuntimeException("No matching format: " + format.toString());
+    }
+}
+
+/** @hide */
+class Cea708CaptionTrack extends SubtitleTrack {
+    private final Cea708CCParser mCCParser;
+    private final Cea708CCWidget mRenderingWidget;
+
+    Cea708CaptionTrack(Cea708CCWidget renderingWidget, MediaFormat format) {
+        super(format);
+
+        mRenderingWidget = renderingWidget;
+        mCCParser = new Cea708CCParser(mRenderingWidget);
+    }
+
+    @Override
+    public void onData(byte[] data, boolean eos, long runID) {
+        mCCParser.parse(data);
+    }
+
+    @Override
+    public RenderingWidget getRenderingWidget() {
+        return mRenderingWidget;
+    }
+
+    @Override
+    public void updateView(Vector<Cue> activeCues) {
+        // Overriding with NO-OP, CC rendering by-passes this
+    }
+}
+
+/**
+ * @hide
+ *
+ * A class for parsing CEA-708, which is the standard for closed captioning for ATSC DTV.
+ *
+ * <p>ATSC DTV closed caption data are carried on picture user data of video streams.
+ * This class starts to parse from picture user data payload, so extraction process of user_data
+ * from video streams is up to outside of this code.
+ *
+ * <p>There are 4 steps to decode user_data to provide closed caption services. Step 1 and 2 are
+ * done in NuPlayer and libstagefright.
+ *
+ * <h3>Step 1. user_data -&gt; CcPacket</h3>
+ *
+ * <p>First, user_data consists of cc_data packets, which are 3-byte segments. Here, CcPacket is a
+ * collection of cc_data packets in a frame along with same presentation timestamp. Because cc_data
+ * packets must be reassembled in the frame display order, CcPackets are reordered.
+ *
+ * <h3>Step 2. CcPacket -&gt; DTVCC packet</h3>
+ *
+ * <p>Each cc_data packet has a one byte for declaring a type of itself and data validity, and the
+ * subsequent two bytes for input data of a DTVCC packet. There are 4 types for cc_data packet.
+ * We're interested in DTVCC_PACKET_START(type 3) and DTVCC_PACKET_DATA(type 2). Each DTVCC packet
+ * begins with DTVCC_PACKET_START(type 3) and the following cc_data packets which has
+ * DTVCC_PACKET_DATA(type 2) are appended into the DTVCC packet being assembled.
+ *
+ * <h3>Step 3. DTVCC packet -&gt; Service Blocks</h3>
+ *
+ * <p>A DTVCC packet consists of multiple service blocks. Each service block represents a caption
+ * track and has a service number, which ranges from 1 to 63, that denotes caption track identity.
+ * In here, we listen at most one chosen caption track by service number. Otherwise, just skip the
+ * other service blocks.
+ *
+ * <h3>Step 4. Interpreting Service Block Data ({@link #parseServiceBlockData}, {@code parseXX},
+ * and {@link #parseExt1} methods)</h3>
+ *
+ * <p>Service block data is actual caption stream. it looks similar to telnet. It uses most parts of
+ * ASCII table and consists of specially defined commands and some ASCII control codes which work
+ * in a behavior slightly different from their original purpose. ASCII control codes and caption
+ * commands are explicit instructions that control the state of a closed caption service and the
+ * other ASCII and text codes are implicit instructions that send their characters to buffer.
+ *
+ * <p>There are 4 main code groups and 4 extended code groups. Both the range of code groups are the
+ * same as the range of a byte.
+ *
+ * <p>4 main code groups: C0, C1, G0, G1
+ * <br>4 extended code groups: C2, C3, G2, G3
+ *
+ * <p>Each code group has its own handle method. For example, {@link #parseC0} handles C0 code group
+ * and so on. And {@link #parseServiceBlockData} method maps a stream on the main code groups while
+ * {@link #parseExt1} method maps on the extended code groups.
+ *
+ * <p>The main code groups:
+ * <ul>
+ * <li>C0 - contains modified ASCII control codes. It is not intended by CEA-708 but Korea TTA
+ *      standard for ATSC CC uses P16 character heavily, which is unclear entity in CEA-708 doc,
+ *      even for the alphanumeric characters instead of ASCII characters.</li>
+ * <li>C1 - contains the caption commands. There are 3 categories of a caption command.</li>
+ * <ul>
+ * <li>Window commands: The window commands control a caption window which is addressable area being
+ *                  with in the Safe title area. (CWX, CLW, DSW, HDW, TGW, DLW, SWA, DFX)</li>
+ * <li>Pen commands: Th pen commands control text style and location. (SPA, SPC, SPL)</li>
+ * <li>Job commands: The job commands make a delay and recover from the delay. (DLY, DLC, RST)</li>
+ * </ul>
+ * <li>G0 - same as printable ASCII character set except music note character.</li>
+ * <li>G1 - same as ISO 8859-1 Latin 1 character set.</li>
+ * </ul>
+ * <p>Most of the extended code groups are being skipped.
+ *
+ */
+class Cea708CCParser {
+    private static final String TAG = "Cea708CCParser";
+    private static final boolean DEBUG = false;
+
+    private static final String MUSIC_NOTE_CHAR = new String(
+            "\u266B".getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
+
+    private final StringBuffer mBuffer = new StringBuffer();
+    private int mCommand = 0;
+
+    // Assign a dummy listener in order to avoid null checks.
+    private DisplayListener mListener = new DisplayListener() {
+        @Override
+        public void emitEvent(CaptionEvent event) {
+            // do nothing
+        }
+    };
+
+    /**
+     * {@link Cea708Parser} emits caption event of three different types.
+     * {@link DisplayListener#emitEvent} is invoked with the parameter
+     * {@link CaptionEvent} to pass all the results to an observer of the decoding process .
+     *
+     * <p>{@link CaptionEvent#type} determines the type of the result and
+     * {@link CaptionEvent#obj} contains the output value of a caption event.
+     * The observer must do the casting to the corresponding type.
+     *
+     * <ul><li>{@code CAPTION_EMIT_TYPE_BUFFER}: Passes a caption text buffer to a observer.
+     * {@code obj} must be of {@link String}.</li>
+     *
+     * <li>{@code CAPTION_EMIT_TYPE_CONTROL}: Passes a caption character control code to a observer.
+     * {@code obj} must be of {@link Character}.</li>
+     *
+     * <li>{@code CAPTION_EMIT_TYPE_CLEAR_COMMAND}: Passes a clear command to a observer.
+     * {@code obj} must be {@code NULL}.</li></ul>
+     */
+    public static final int CAPTION_EMIT_TYPE_BUFFER = 1;
+    public static final int CAPTION_EMIT_TYPE_CONTROL = 2;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_CWX = 3;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_CLW = 4;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_DSW = 5;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_HDW = 6;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_TGW = 7;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_DLW = 8;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_DLY = 9;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_DLC = 10;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_RST = 11;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_SPA = 12;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_SPC = 13;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_SPL = 14;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_SWA = 15;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_DFX = 16;
+
+    Cea708CCParser(DisplayListener listener) {
+        if (listener != null) {
+            mListener = listener;
+        }
+    }
+
+    interface DisplayListener {
+        void emitEvent(CaptionEvent event);
+    }
+
+    private void emitCaptionEvent(CaptionEvent captionEvent) {
+        // Emit the existing string buffer before a new event is arrived.
+        emitCaptionBuffer();
+        mListener.emitEvent(captionEvent);
+    }
+
+    private void emitCaptionBuffer() {
+        if (mBuffer.length() > 0) {
+            mListener.emitEvent(new CaptionEvent(CAPTION_EMIT_TYPE_BUFFER, mBuffer.toString()));
+            mBuffer.setLength(0);
+        }
+    }
+
+    // Step 3. DTVCC packet -> Service Blocks (parseDtvCcPacket method)
+    public void parse(byte[] data) {
+        // From this point, starts to read DTVCC coding layer.
+        // First, identify code groups, which is defined in CEA-708B Section 7.1.
+        int pos = 0;
+        while (pos < data.length) {
+            pos = parseServiceBlockData(data, pos);
+        }
+
+        // Emit the buffer after reading codes.
+        emitCaptionBuffer();
+    }
+
+    // Step 4. Main code groups
+    private int parseServiceBlockData(byte[] data, int pos) {
+        // For the details of the ranges of DTVCC code groups, see CEA-708B Table 6.
+        mCommand = data[pos] & 0xff;
+        ++pos;
+        if (mCommand == Const.CODE_C0_EXT1) {
+            if (DEBUG) {
+                Log.d(TAG, String.format("parseServiceBlockData EXT1 %x", mCommand));
+            }
+            pos = parseExt1(data, pos);
+        } else if (mCommand >= Const.CODE_C0_RANGE_START
+                && mCommand <= Const.CODE_C0_RANGE_END) {
+            if (DEBUG) {
+                Log.d(TAG, String.format("parseServiceBlockData C0 %x", mCommand));
+            }
+            pos = parseC0(data, pos);
+        } else if (mCommand >= Const.CODE_C1_RANGE_START
+                && mCommand <= Const.CODE_C1_RANGE_END) {
+            if (DEBUG) {
+                Log.d(TAG, String.format("parseServiceBlockData C1 %x", mCommand));
+            }
+            pos = parseC1(data, pos);
+        } else if (mCommand >= Const.CODE_G0_RANGE_START
+                && mCommand <= Const.CODE_G0_RANGE_END) {
+            if (DEBUG) {
+                Log.d(TAG, String.format("parseServiceBlockData G0 %x", mCommand));
+            }
+            pos = parseG0(data, pos);
+        } else if (mCommand >= Const.CODE_G1_RANGE_START
+                && mCommand <= Const.CODE_G1_RANGE_END) {
+            if (DEBUG) {
+                Log.d(TAG, String.format("parseServiceBlockData G1 %x", mCommand));
+            }
+            pos = parseG1(data, pos);
+        }
+        return pos;
+    }
+
+    private int parseC0(byte[] data, int pos) {
+        // For the details of C0 code group, see CEA-708B Section 7.4.1.
+        // CL Group: C0 Subset of ASCII Control codes
+        if (mCommand >= Const.CODE_C0_SKIP2_RANGE_START
+                && mCommand <= Const.CODE_C0_SKIP2_RANGE_END) {
+            if (mCommand == Const.CODE_C0_P16) {
+                // P16 escapes next two bytes for the large character maps.(no standard rule)
+                // For Korea broadcasting, express whole letters by using this.
+                try {
+                    if (data[pos] == 0) {
+                        mBuffer.append((char) data[pos + 1]);
+                    } else {
+                        String value = new String(Arrays.copyOfRange(data, pos, pos + 2), "EUC-KR");
+                        mBuffer.append(value);
+                    }
+                } catch (UnsupportedEncodingException e) {
+                    Log.e(TAG, "P16 Code - Could not find supported encoding", e);
+                }
+            }
+            pos += 2;
+        } else if (mCommand >= Const.CODE_C0_SKIP1_RANGE_START
+                && mCommand <= Const.CODE_C0_SKIP1_RANGE_END) {
+            ++pos;
+        } else {
+            // NUL, BS, FF, CR interpreted as they are in ASCII control codes.
+            // HCR moves the pen location to th beginning of the current line and deletes contents.
+            // FF clears the screen and moves the pen location to (0,0).
+            // ETX is the NULL command which is used to flush text to the current window when no
+            // other command is pending.
+            switch (mCommand) {
+                case Const.CODE_C0_NUL:
+                    break;
+                case Const.CODE_C0_ETX:
+                    emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_CONTROL, (char) mCommand));
+                    break;
+                case Const.CODE_C0_BS:
+                    emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_CONTROL, (char) mCommand));
+                    break;
+                case Const.CODE_C0_FF:
+                    emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_CONTROL, (char) mCommand));
+                    break;
+                case Const.CODE_C0_CR:
+                    mBuffer.append('\n');
+                    break;
+                case Const.CODE_C0_HCR:
+                    emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_CONTROL, (char) mCommand));
+                    break;
+                default:
+                    break;
+            }
+        }
+        return pos;
+    }
+
+    private int parseC1(byte[] data, int pos) {
+        // For the details of C1 code group, see CEA-708B Section 8.10.
+        // CR Group: C1 Caption Control Codes
+        switch (mCommand) {
+            case Const.CODE_C1_CW0:
+            case Const.CODE_C1_CW1:
+            case Const.CODE_C1_CW2:
+            case Const.CODE_C1_CW3:
+            case Const.CODE_C1_CW4:
+            case Const.CODE_C1_CW5:
+            case Const.CODE_C1_CW6:
+            case Const.CODE_C1_CW7: {
+                // SetCurrentWindow0-7
+                int windowId = mCommand - Const.CODE_C1_CW0;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_CWX, windowId));
+                if (DEBUG) {
+                    Log.d(TAG, String.format("CaptionCommand CWX windowId: %d", windowId));
+                }
+                break;
+            }
+
+            case Const.CODE_C1_CLW: {
+                // ClearWindows
+                int windowBitmap = data[pos] & 0xff;
+                ++pos;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_CLW, windowBitmap));
+                if (DEBUG) {
+                    Log.d(TAG, String.format("CaptionCommand CLW windowBitmap: %d", windowBitmap));
+                }
+                break;
+            }
+
+            case Const.CODE_C1_DSW: {
+                // DisplayWindows
+                int windowBitmap = data[pos] & 0xff;
+                ++pos;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_DSW, windowBitmap));
+                if (DEBUG) {
+                    Log.d(TAG, String.format("CaptionCommand DSW windowBitmap: %d", windowBitmap));
+                }
+                break;
+            }
+
+            case Const.CODE_C1_HDW: {
+                // HideWindows
+                int windowBitmap = data[pos] & 0xff;
+                ++pos;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_HDW, windowBitmap));
+                if (DEBUG) {
+                    Log.d(TAG, String.format("CaptionCommand HDW windowBitmap: %d", windowBitmap));
+                }
+                break;
+            }
+
+            case Const.CODE_C1_TGW: {
+                // ToggleWindows
+                int windowBitmap = data[pos] & 0xff;
+                ++pos;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_TGW, windowBitmap));
+                if (DEBUG) {
+                    Log.d(TAG, String.format("CaptionCommand TGW windowBitmap: %d", windowBitmap));
+                }
+                break;
+            }
+
+            case Const.CODE_C1_DLW: {
+                // DeleteWindows
+                int windowBitmap = data[pos] & 0xff;
+                ++pos;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_DLW, windowBitmap));
+                if (DEBUG) {
+                    Log.d(TAG, String.format("CaptionCommand DLW windowBitmap: %d", windowBitmap));
+                }
+                break;
+            }
+
+            case Const.CODE_C1_DLY: {
+                // Delay
+                int tenthsOfSeconds = data[pos] & 0xff;
+                ++pos;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_DLY, tenthsOfSeconds));
+                if (DEBUG) {
+                    Log.d(TAG, String.format("CaptionCommand DLY %d tenths of seconds",
+                            tenthsOfSeconds));
+                }
+                break;
+            }
+            case Const.CODE_C1_DLC: {
+                // DelayCancel
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_DLC, null));
+                if (DEBUG) {
+                    Log.d(TAG, "CaptionCommand DLC");
+                }
+                break;
+            }
+
+            case Const.CODE_C1_RST: {
+                // Reset
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_RST, null));
+                if (DEBUG) {
+                    Log.d(TAG, "CaptionCommand RST");
+                }
+                break;
+            }
+
+            case Const.CODE_C1_SPA: {
+                // SetPenAttributes
+                int textTag = (data[pos] & 0xf0) >> 4;
+                int penSize = data[pos] & 0x03;
+                int penOffset = (data[pos] & 0x0c) >> 2;
+                boolean italic = (data[pos + 1] & 0x80) != 0;
+                boolean underline = (data[pos + 1] & 0x40) != 0;
+                int edgeType = (data[pos + 1] & 0x38) >> 3;
+                int fontTag = data[pos + 1] & 0x7;
+                pos += 2;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_SPA,
+                        new CaptionPenAttr(penSize, penOffset, textTag, fontTag, edgeType,
+                                underline, italic)));
+                if (DEBUG) {
+                    Log.d(TAG, String.format(
+                            "CaptionCommand SPA penSize: %d, penOffset: %d, textTag: %d, "
+                                    + "fontTag: %d, edgeType: %d, underline: %s, italic: %s",
+                            penSize, penOffset, textTag, fontTag, edgeType, underline, italic));
+                }
+                break;
+            }
+
+            case Const.CODE_C1_SPC: {
+                // SetPenColor
+                int opacity = (data[pos] & 0xc0) >> 6;
+                int red = (data[pos] & 0x30) >> 4;
+                int green = (data[pos] & 0x0c) >> 2;
+                int blue = data[pos] & 0x03;
+                CaptionColor foregroundColor = new CaptionColor(opacity, red, green, blue);
+                ++pos;
+                opacity = (data[pos] & 0xc0) >> 6;
+                red = (data[pos] & 0x30) >> 4;
+                green = (data[pos] & 0x0c) >> 2;
+                blue = data[pos] & 0x03;
+                CaptionColor backgroundColor = new CaptionColor(opacity, red, green, blue);
+                ++pos;
+                red = (data[pos] & 0x30) >> 4;
+                green = (data[pos] & 0x0c) >> 2;
+                blue = data[pos] & 0x03;
+                CaptionColor edgeColor = new CaptionColor(
+                        CaptionColor.OPACITY_SOLID, red, green, blue);
+                ++pos;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_SPC,
+                        new CaptionPenColor(foregroundColor, backgroundColor, edgeColor)));
+                if (DEBUG) {
+                    Log.d(TAG, String.format(
+                            "CaptionCommand SPC foregroundColor %s backgroundColor %s edgeColor %s",
+                            foregroundColor, backgroundColor, edgeColor));
+                }
+                break;
+            }
+
+            case Const.CODE_C1_SPL: {
+                // SetPenLocation
+                // column is normally 0-31 for 4:3 formats, and 0-41 for 16:9 formats
+                int row = data[pos] & 0x0f;
+                int column = data[pos + 1] & 0x3f;
+                pos += 2;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_SPL,
+                        new CaptionPenLocation(row, column)));
+                if (DEBUG) {
+                    Log.d(TAG, String.format("CaptionCommand SPL row: %d, column: %d",
+                            row, column));
+                }
+                break;
+            }
+
+            case Const.CODE_C1_SWA: {
+                // SetWindowAttributes
+                int opacity = (data[pos] & 0xc0) >> 6;
+                int red = (data[pos] & 0x30) >> 4;
+                int green = (data[pos] & 0x0c) >> 2;
+                int blue = data[pos] & 0x03;
+                CaptionColor fillColor = new CaptionColor(opacity, red, green, blue);
+                int borderType = (data[pos + 1] & 0xc0) >> 6 | (data[pos + 2] & 0x80) >> 5;
+                red = (data[pos + 1] & 0x30) >> 4;
+                green = (data[pos + 1] & 0x0c) >> 2;
+                blue = data[pos + 1] & 0x03;
+                CaptionColor borderColor = new CaptionColor(
+                        CaptionColor.OPACITY_SOLID, red, green, blue);
+                boolean wordWrap = (data[pos + 2] & 0x40) != 0;
+                int printDirection = (data[pos + 2] & 0x30) >> 4;
+                int scrollDirection = (data[pos + 2] & 0x0c) >> 2;
+                int justify = (data[pos + 2] & 0x03);
+                int effectSpeed = (data[pos + 3] & 0xf0) >> 4;
+                int effectDirection = (data[pos + 3] & 0x0c) >> 2;
+                int displayEffect = data[pos + 3] & 0x3;
+                pos += 4;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_SWA,
+                        new CaptionWindowAttr(fillColor, borderColor, borderType, wordWrap,
+                                printDirection, scrollDirection, justify,
+                                effectDirection, effectSpeed, displayEffect)));
+                if (DEBUG) {
+                    Log.d(TAG, String.format(
+                            "CaptionCommand SWA fillColor: %s, borderColor: %s, borderType: %d"
+                                    + "wordWrap: %s, printDirection: %d, scrollDirection: %d, "
+                                    + "justify: %s, effectDirection: %d, effectSpeed: %d, "
+                                    + "displayEffect: %d",
+                            fillColor, borderColor, borderType, wordWrap, printDirection,
+                            scrollDirection, justify, effectDirection, effectSpeed, displayEffect));
+                }
+                break;
+            }
+
+            case Const.CODE_C1_DF0:
+            case Const.CODE_C1_DF1:
+            case Const.CODE_C1_DF2:
+            case Const.CODE_C1_DF3:
+            case Const.CODE_C1_DF4:
+            case Const.CODE_C1_DF5:
+            case Const.CODE_C1_DF6:
+            case Const.CODE_C1_DF7: {
+                // DefineWindow0-7
+                int windowId = mCommand - Const.CODE_C1_DF0;
+                boolean visible = (data[pos] & 0x20) != 0;
+                boolean rowLock = (data[pos] & 0x10) != 0;
+                boolean columnLock = (data[pos] & 0x08) != 0;
+                int priority = data[pos] & 0x07;
+                boolean relativePositioning = (data[pos + 1] & 0x80) != 0;
+                int anchorVertical = data[pos + 1] & 0x7f;
+                int anchorHorizontal = data[pos + 2] & 0xff;
+                int anchorId = (data[pos + 3] & 0xf0) >> 4;
+                int rowCount = data[pos + 3] & 0x0f;
+                int columnCount = data[pos + 4] & 0x3f;
+                int windowStyle = (data[pos + 5] & 0x38) >> 3;
+                int penStyle = data[pos + 5] & 0x07;
+                pos += 6;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_DFX,
+                        new CaptionWindow(windowId, visible, rowLock, columnLock, priority,
+                                relativePositioning, anchorVertical, anchorHorizontal, anchorId,
+                                rowCount, columnCount, penStyle, windowStyle)));
+                if (DEBUG) {
+                    Log.d(TAG, String.format(
+                            "CaptionCommand DFx windowId: %d, priority: %d, columnLock: %s, "
+                                    + "rowLock: %s, visible: %s, anchorVertical: %d, "
+                                    + "relativePositioning: %s, anchorHorizontal: %d, "
+                                    + "rowCount: %d, anchorId: %d, columnCount: %d, penStyle: %d, "
+                                    + "windowStyle: %d",
+                            windowId, priority, columnLock, rowLock, visible, anchorVertical,
+                            relativePositioning, anchorHorizontal, rowCount, anchorId, columnCount,
+                            penStyle, windowStyle));
+                }
+                break;
+            }
+
+            default:
+                break;
+        }
+        return pos;
+    }
+
+    private int parseG0(byte[] data, int pos) {
+        // For the details of G0 code group, see CEA-708B Section 7.4.3.
+        // GL Group: G0 Modified version of ANSI X3.4 Printable Character Set (ASCII)
+        if (mCommand == Const.CODE_G0_MUSICNOTE) {
+            // Music note.
+            mBuffer.append(MUSIC_NOTE_CHAR);
+        } else {
+            // Put ASCII code into buffer.
+            mBuffer.append((char) mCommand);
+        }
+        return pos;
+    }
+
+    private int parseG1(byte[] data, int pos) {
+        // For the details of G0 code group, see CEA-708B Section 7.4.4.
+        // GR Group: G1 ISO 8859-1 Latin 1 Characters
+        // Put ASCII Extended character set into buffer.
+        mBuffer.append((char) mCommand);
+        return pos;
+    }
+
+    // Step 4. Extended code groups
+    private int parseExt1(byte[] data, int pos) {
+        // For the details of EXT1 code group, see CEA-708B Section 7.2.
+        mCommand = data[pos] & 0xff;
+        ++pos;
+        if (mCommand >= Const.CODE_C2_RANGE_START
+                && mCommand <= Const.CODE_C2_RANGE_END) {
+            pos = parseC2(data, pos);
+        } else if (mCommand >= Const.CODE_C3_RANGE_START
+                && mCommand <= Const.CODE_C3_RANGE_END) {
+            pos = parseC3(data, pos);
+        } else if (mCommand >= Const.CODE_G2_RANGE_START
+                && mCommand <= Const.CODE_G2_RANGE_END) {
+            pos = parseG2(data, pos);
+        } else if (mCommand >= Const.CODE_G3_RANGE_START
+                && mCommand <= Const.CODE_G3_RANGE_END) {
+            pos = parseG3(data ,pos);
+        }
+        return pos;
+    }
+
+    private int parseC2(byte[] data, int pos) {
+        // For the details of C2 code group, see CEA-708B Section 7.4.7.
+        // Extended Miscellaneous Control Codes
+        // C2 Table : No commands as of CEA-708B. A decoder must skip.
+        if (mCommand >= Const.CODE_C2_SKIP0_RANGE_START
+                && mCommand <= Const.CODE_C2_SKIP0_RANGE_END) {
+            // Do nothing.
+        } else if (mCommand >= Const.CODE_C2_SKIP1_RANGE_START
+                && mCommand <= Const.CODE_C2_SKIP1_RANGE_END) {
+            ++pos;
+        } else if (mCommand >= Const.CODE_C2_SKIP2_RANGE_START
+                && mCommand <= Const.CODE_C2_SKIP2_RANGE_END) {
+            pos += 2;
+        } else if (mCommand >= Const.CODE_C2_SKIP3_RANGE_START
+                && mCommand <= Const.CODE_C2_SKIP3_RANGE_END) {
+            pos += 3;
+        }
+        return pos;
+    }
+
+    private int parseC3(byte[] data, int pos) {
+        // For the details of C3 code group, see CEA-708B Section 7.4.8.
+        // Extended Control Code Set 2
+        // C3 Table : No commands as of CEA-708B. A decoder must skip.
+        if (mCommand >= Const.CODE_C3_SKIP4_RANGE_START
+                && mCommand <= Const.CODE_C3_SKIP4_RANGE_END) {
+            pos += 4;
+        } else if (mCommand >= Const.CODE_C3_SKIP5_RANGE_START
+                && mCommand <= Const.CODE_C3_SKIP5_RANGE_END) {
+            pos += 5;
+        }
+        return pos;
+    }
+
+    private int parseG2(byte[] data, int pos) {
+        // For the details of C3 code group, see CEA-708B Section 7.4.5.
+        // Extended Control Code Set 1(G2 Table)
+        switch (mCommand) {
+            case Const.CODE_G2_TSP:
+                // TODO : TSP is the Transparent space
+                break;
+            case Const.CODE_G2_NBTSP:
+                // TODO : NBTSP is Non-Breaking Transparent Space.
+                break;
+            case Const.CODE_G2_BLK:
+                // TODO : BLK indicates a solid block which fills the entire character block
+                // TODO : with a solid foreground color.
+                break;
+            default:
+                break;
+        }
+        return pos;
+    }
+
+    private int parseG3(byte[] data, int pos) {
+        // For the details of C3 code group, see CEA-708B Section 7.4.6.
+        // Future characters and icons(G3 Table)
+        if (mCommand == Const.CODE_G3_CC) {
+            // TODO : [CC] icon with square corners
+        }
+
+        // Do nothing
+        return pos;
+    }
+
+    /**
+     * @hide
+     *
+     * Collection of CEA-708 structures.
+     */
+    private static class Const {
+
+        private Const() {
+        }
+
+        // For the details of the ranges of DTVCC code groups, see CEA-708B Table 6.
+        public static final int CODE_C0_RANGE_START = 0x00;
+        public static final int CODE_C0_RANGE_END = 0x1f;
+        public static final int CODE_C1_RANGE_START = 0x80;
+        public static final int CODE_C1_RANGE_END = 0x9f;
+        public static final int CODE_G0_RANGE_START = 0x20;
+        public static final int CODE_G0_RANGE_END = 0x7f;
+        public static final int CODE_G1_RANGE_START = 0xa0;
+        public static final int CODE_G1_RANGE_END = 0xff;
+        public static final int CODE_C2_RANGE_START = 0x00;
+        public static final int CODE_C2_RANGE_END = 0x1f;
+        public static final int CODE_C3_RANGE_START = 0x80;
+        public static final int CODE_C3_RANGE_END = 0x9f;
+        public static final int CODE_G2_RANGE_START = 0x20;
+        public static final int CODE_G2_RANGE_END = 0x7f;
+        public static final int CODE_G3_RANGE_START = 0xa0;
+        public static final int CODE_G3_RANGE_END = 0xff;
+
+        // The following ranges are defined in CEA-708B Section 7.4.1.
+        public static final int CODE_C0_SKIP2_RANGE_START = 0x18;
+        public static final int CODE_C0_SKIP2_RANGE_END = 0x1f;
+        public static final int CODE_C0_SKIP1_RANGE_START = 0x10;
+        public static final int CODE_C0_SKIP1_RANGE_END = 0x17;
+
+        // The following ranges are defined in CEA-708B Section 7.4.7.
+        public static final int CODE_C2_SKIP0_RANGE_START = 0x00;
+        public static final int CODE_C2_SKIP0_RANGE_END = 0x07;
+        public static final int CODE_C2_SKIP1_RANGE_START = 0x08;
+        public static final int CODE_C2_SKIP1_RANGE_END = 0x0f;
+        public static final int CODE_C2_SKIP2_RANGE_START = 0x10;
+        public static final int CODE_C2_SKIP2_RANGE_END = 0x17;
+        public static final int CODE_C2_SKIP3_RANGE_START = 0x18;
+        public static final int CODE_C2_SKIP3_RANGE_END = 0x1f;
+
+        // The following ranges are defined in CEA-708B Section 7.4.8.
+        public static final int CODE_C3_SKIP4_RANGE_START = 0x80;
+        public static final int CODE_C3_SKIP4_RANGE_END = 0x87;
+        public static final int CODE_C3_SKIP5_RANGE_START = 0x88;
+        public static final int CODE_C3_SKIP5_RANGE_END = 0x8f;
+
+        // The following values are the special characters of CEA-708 spec.
+        public static final int CODE_C0_NUL = 0x00;
+        public static final int CODE_C0_ETX = 0x03;
+        public static final int CODE_C0_BS = 0x08;
+        public static final int CODE_C0_FF = 0x0c;
+        public static final int CODE_C0_CR = 0x0d;
+        public static final int CODE_C0_HCR = 0x0e;
+        public static final int CODE_C0_EXT1 = 0x10;
+        public static final int CODE_C0_P16 = 0x18;
+        public static final int CODE_G0_MUSICNOTE = 0x7f;
+        public static final int CODE_G2_TSP = 0x20;
+        public static final int CODE_G2_NBTSP = 0x21;
+        public static final int CODE_G2_BLK = 0x30;
+        public static final int CODE_G3_CC = 0xa0;
+
+        // The following values are the command bits of CEA-708 spec.
+        public static final int CODE_C1_CW0 = 0x80;
+        public static final int CODE_C1_CW1 = 0x81;
+        public static final int CODE_C1_CW2 = 0x82;
+        public static final int CODE_C1_CW3 = 0x83;
+        public static final int CODE_C1_CW4 = 0x84;
+        public static final int CODE_C1_CW5 = 0x85;
+        public static final int CODE_C1_CW6 = 0x86;
+        public static final int CODE_C1_CW7 = 0x87;
+        public static final int CODE_C1_CLW = 0x88;
+        public static final int CODE_C1_DSW = 0x89;
+        public static final int CODE_C1_HDW = 0x8a;
+        public static final int CODE_C1_TGW = 0x8b;
+        public static final int CODE_C1_DLW = 0x8c;
+        public static final int CODE_C1_DLY = 0x8d;
+        public static final int CODE_C1_DLC = 0x8e;
+        public static final int CODE_C1_RST = 0x8f;
+        public static final int CODE_C1_SPA = 0x90;
+        public static final int CODE_C1_SPC = 0x91;
+        public static final int CODE_C1_SPL = 0x92;
+        public static final int CODE_C1_SWA = 0x97;
+        public static final int CODE_C1_DF0 = 0x98;
+        public static final int CODE_C1_DF1 = 0x99;
+        public static final int CODE_C1_DF2 = 0x9a;
+        public static final int CODE_C1_DF3 = 0x9b;
+        public static final int CODE_C1_DF4 = 0x9c;
+        public static final int CODE_C1_DF5 = 0x9d;
+        public static final int CODE_C1_DF6 = 0x9e;
+        public static final int CODE_C1_DF7 = 0x9f;
+    }
+
+    /**
+     * @hide
+     *
+     * CEA-708B-specific color.
+     */
+    public static class CaptionColor {
+        public static final int OPACITY_SOLID = 0;
+        public static final int OPACITY_FLASH = 1;
+        public static final int OPACITY_TRANSLUCENT = 2;
+        public static final int OPACITY_TRANSPARENT = 3;
+
+        private static final int[] COLOR_MAP = new int[] { 0x00, 0x0f, 0xf0, 0xff };
+        private static final int[] OPACITY_MAP = new int[] { 0xff, 0xfe, 0x80, 0x00 };
+
+        public final int opacity;
+        public final int red;
+        public final int green;
+        public final int blue;
+
+        public CaptionColor(int opacity, int red, int green, int blue) {
+            this.opacity = opacity;
+            this.red = red;
+            this.green = green;
+            this.blue = blue;
+        }
+
+        public int getArgbValue() {
+            return Color.argb(
+                    OPACITY_MAP[opacity], COLOR_MAP[red], COLOR_MAP[green], COLOR_MAP[blue]);
+        }
+    }
+
+    /**
+     * @hide
+     *
+     * Caption event generated by {@link Cea708CCParser}.
+     */
+    public static class CaptionEvent {
+        public final int type;
+        public final Object obj;
+
+        public CaptionEvent(int type, Object obj) {
+            this.type = type;
+            this.obj = obj;
+        }
+    }
+
+    /**
+     * @hide
+     *
+     * Pen style information.
+     */
+    public static class CaptionPenAttr {
+        // Pen sizes
+        public static final int PEN_SIZE_SMALL = 0;
+        public static final int PEN_SIZE_STANDARD = 1;
+        public static final int PEN_SIZE_LARGE = 2;
+
+        // Offsets
+        public static final int OFFSET_SUBSCRIPT = 0;
+        public static final int OFFSET_NORMAL = 1;
+        public static final int OFFSET_SUPERSCRIPT = 2;
+
+        public final int penSize;
+        public final int penOffset;
+        public final int textTag;
+        public final int fontTag;
+        public final int edgeType;
+        public final boolean underline;
+        public final boolean italic;
+
+        public CaptionPenAttr(int penSize, int penOffset, int textTag, int fontTag, int edgeType,
+                boolean underline, boolean italic) {
+            this.penSize = penSize;
+            this.penOffset = penOffset;
+            this.textTag = textTag;
+            this.fontTag = fontTag;
+            this.edgeType = edgeType;
+            this.underline = underline;
+            this.italic = italic;
+        }
+    }
+
+    /**
+     * @hide
+     *
+     * {@link CaptionColor} objects that indicate the foreground, background, and edge color of a
+     * pen.
+     */
+    public static class CaptionPenColor {
+        public final CaptionColor foregroundColor;
+        public final CaptionColor backgroundColor;
+        public final CaptionColor edgeColor;
+
+        public CaptionPenColor(CaptionColor foregroundColor, CaptionColor backgroundColor,
+                CaptionColor edgeColor) {
+            this.foregroundColor = foregroundColor;
+            this.backgroundColor = backgroundColor;
+            this.edgeColor = edgeColor;
+        }
+    }
+
+    /**
+     * @hide
+     *
+     * Location information of a pen.
+     */
+    public static class CaptionPenLocation {
+        public final int row;
+        public final int column;
+
+        public CaptionPenLocation(int row, int column) {
+            this.row = row;
+            this.column = column;
+        }
+    }
+
+    /**
+     * @hide
+     *
+     * Attributes of a caption window, which is defined in CEA-708B.
+     */
+    public static class CaptionWindowAttr {
+        public final CaptionColor fillColor;
+        public final CaptionColor borderColor;
+        public final int borderType;
+        public final boolean wordWrap;
+        public final int printDirection;
+        public final int scrollDirection;
+        public final int justify;
+        public final int effectDirection;
+        public final int effectSpeed;
+        public final int displayEffect;
+
+        public CaptionWindowAttr(CaptionColor fillColor, CaptionColor borderColor, int borderType,
+                boolean wordWrap, int printDirection, int scrollDirection, int justify,
+                int effectDirection,
+                int effectSpeed, int displayEffect) {
+            this.fillColor = fillColor;
+            this.borderColor = borderColor;
+            this.borderType = borderType;
+            this.wordWrap = wordWrap;
+            this.printDirection = printDirection;
+            this.scrollDirection = scrollDirection;
+            this.justify = justify;
+            this.effectDirection = effectDirection;
+            this.effectSpeed = effectSpeed;
+            this.displayEffect = displayEffect;
+        }
+    }
+
+    /**
+     * @hide
+     *
+     * Construction information of the caption window of CEA-708B.
+     */
+    public static class CaptionWindow {
+        public final int id;
+        public final boolean visible;
+        public final boolean rowLock;
+        public final boolean columnLock;
+        public final int priority;
+        public final boolean relativePositioning;
+        public final int anchorVertical;
+        public final int anchorHorizontal;
+        public final int anchorId;
+        public final int rowCount;
+        public final int columnCount;
+        public final int penStyle;
+        public final int windowStyle;
+
+        public CaptionWindow(int id, boolean visible,
+                boolean rowLock, boolean columnLock, int priority, boolean relativePositioning,
+                int anchorVertical, int anchorHorizontal, int anchorId,
+                int rowCount, int columnCount, int penStyle, int windowStyle) {
+            this.id = id;
+            this.visible = visible;
+            this.rowLock = rowLock;
+            this.columnLock = columnLock;
+            this.priority = priority;
+            this.relativePositioning = relativePositioning;
+            this.anchorVertical = anchorVertical;
+            this.anchorHorizontal = anchorHorizontal;
+            this.anchorId = anchorId;
+            this.rowCount = rowCount;
+            this.columnCount = columnCount;
+            this.penStyle = penStyle;
+            this.windowStyle = windowStyle;
+        }
+    }
+}
+
+/**
+ * Widget capable of rendering CEA-708 closed captions.
+ *
+ * @hide
+ */
+class Cea708CCWidget extends ClosedCaptionWidget implements Cea708CCParser.DisplayListener {
+    private final CCHandler mCCHandler;
+
+    public Cea708CCWidget(Context context) {
+        this(context, null);
+    }
+
+    public Cea708CCWidget(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public Cea708CCWidget(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public Cea708CCWidget(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        mCCHandler = new CCHandler((CCLayout) mClosedCaptionLayout);
+    }
+
+    @Override
+    public ClosedCaptionLayout createCaptionLayout(Context context) {
+        return new CCLayout(context);
+    }
+
+    @Override
+    public void emitEvent(Cea708CCParser.CaptionEvent event) {
+        mCCHandler.processCaptionEvent(event);
+
+        setSize(getWidth(), getHeight());
+
+        if (mListener != null) {
+            mListener.onChanged(this);
+        }
+    }
+
+    @Override
+    public void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+        ((ViewGroup) mClosedCaptionLayout).draw(canvas);
+    }
+
+    /**
+     * @hide
+     *
+     * A layout that scales its children using the given percentage value.
+     */
+    static class ScaledLayout extends ViewGroup {
+        private static final String TAG = "ScaledLayout";
+        private static final boolean DEBUG = false;
+        private static final Comparator<Rect> mRectTopLeftSorter = new Comparator<Rect>() {
+            @Override
+            public int compare(Rect lhs, Rect rhs) {
+                if (lhs.top != rhs.top) {
+                    return lhs.top - rhs.top;
+                } else {
+                    return lhs.left - rhs.left;
+                }
+            }
+        };
+
+        private Rect[] mRectArray;
+
+        public ScaledLayout(Context context) {
+            super(context);
+        }
+
+        /**
+         * @hide
+         *
+         * ScaledLayoutParams stores the four scale factors.
+         * <br>
+         * Vertical coordinate system:   (scaleStartRow * 100) % ~ (scaleEndRow * 100) %
+         * Horizontal coordinate system: (scaleStartCol * 100) % ~ (scaleEndCol * 100) %
+         * <br>
+         * In XML, for example,
+         * <pre>
+         * {@code
+         * <View
+         *     app:layout_scaleStartRow="0.1"
+         *     app:layout_scaleEndRow="0.5"
+         *     app:layout_scaleStartCol="0.4"
+         *     app:layout_scaleEndCol="1" />
+         * }
+         * </pre>
+         */
+        static class ScaledLayoutParams extends ViewGroup.LayoutParams {
+            public static final float SCALE_UNSPECIFIED = -1;
+            public float scaleStartRow;
+            public float scaleEndRow;
+            public float scaleStartCol;
+            public float scaleEndCol;
+
+            public ScaledLayoutParams(float scaleStartRow, float scaleEndRow,
+                    float scaleStartCol, float scaleEndCol) {
+                super(MATCH_PARENT, MATCH_PARENT);
+                this.scaleStartRow = scaleStartRow;
+                this.scaleEndRow = scaleEndRow;
+                this.scaleStartCol = scaleStartCol;
+                this.scaleEndCol = scaleEndCol;
+            }
+
+            public ScaledLayoutParams(Context context, AttributeSet attrs) {
+                super(MATCH_PARENT, MATCH_PARENT);
+            }
+        }
+
+        @Override
+        public LayoutParams generateLayoutParams(AttributeSet attrs) {
+            return new ScaledLayoutParams(getContext(), attrs);
+        }
+
+        @Override
+        protected boolean checkLayoutParams(LayoutParams p) {
+            return (p instanceof ScaledLayoutParams);
+        }
+
+        @Override
+        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+            int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
+            int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
+            int width = widthSpecSize - getPaddingLeft() - getPaddingRight();
+            int height = heightSpecSize - getPaddingTop() - getPaddingBottom();
+            if (DEBUG) {
+                Log.d(TAG, String.format("onMeasure width: %d, height: %d", width, height));
+            }
+            int count = getChildCount();
+            mRectArray = new Rect[count];
+            for (int i = 0; i < count; ++i) {
+                View child = getChildAt(i);
+                ViewGroup.LayoutParams params = child.getLayoutParams();
+                float scaleStartRow, scaleEndRow, scaleStartCol, scaleEndCol;
+                if (!(params instanceof ScaledLayoutParams)) {
+                    throw new RuntimeException(
+                            "A child of ScaledLayout cannot have the UNSPECIFIED scale factors");
+                }
+                scaleStartRow = ((ScaledLayoutParams) params).scaleStartRow;
+                scaleEndRow = ((ScaledLayoutParams) params).scaleEndRow;
+                scaleStartCol = ((ScaledLayoutParams) params).scaleStartCol;
+                scaleEndCol = ((ScaledLayoutParams) params).scaleEndCol;
+                if (scaleStartRow < 0 || scaleStartRow > 1) {
+                    throw new RuntimeException("A child of ScaledLayout should have a range of "
+                            + "scaleStartRow between 0 and 1");
+                }
+                if (scaleEndRow < scaleStartRow || scaleStartRow > 1) {
+                    throw new RuntimeException("A child of ScaledLayout should have a range of "
+                            + "scaleEndRow between scaleStartRow and 1");
+                }
+                if (scaleEndCol < 0 || scaleEndCol > 1) {
+                    throw new RuntimeException("A child of ScaledLayout should have a range of "
+                            + "scaleStartCol between 0 and 1");
+                }
+                if (scaleEndCol < scaleStartCol || scaleEndCol > 1) {
+                    throw new RuntimeException("A child of ScaledLayout should have a range of "
+                            + "scaleEndCol between scaleStartCol and 1");
+                }
+                if (DEBUG) {
+                    Log.d(TAG, String.format("onMeasure child scaleStartRow: %f scaleEndRow: %f "
+                                    + "scaleStartCol: %f scaleEndCol: %f",
+                            scaleStartRow, scaleEndRow, scaleStartCol, scaleEndCol));
+                }
+                mRectArray[i] = new Rect((int) (scaleStartCol * width), (int) (scaleStartRow
+                        * height), (int) (scaleEndCol * width), (int) (scaleEndRow * height));
+                int childWidthSpec = MeasureSpec.makeMeasureSpec(
+                        (int) (width * (scaleEndCol - scaleStartCol)), MeasureSpec.EXACTLY);
+                int childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+                child.measure(childWidthSpec, childHeightSpec);
+
+                // If the height of the measured child view is bigger than the height of the
+                // calculated region by the given ScaleLayoutParams, the height of the region should
+                // be increased to fit the size of the child view.
+                if (child.getMeasuredHeight() > mRectArray[i].height()) {
+                    int overflowedHeight = child.getMeasuredHeight() - mRectArray[i].height();
+                    overflowedHeight = (overflowedHeight + 1) / 2;
+                    mRectArray[i].bottom += overflowedHeight;
+                    mRectArray[i].top -= overflowedHeight;
+                    if (mRectArray[i].top < 0) {
+                        mRectArray[i].bottom -= mRectArray[i].top;
+                        mRectArray[i].top = 0;
+                    }
+                    if (mRectArray[i].bottom > height) {
+                        mRectArray[i].top -= mRectArray[i].bottom - height;
+                        mRectArray[i].bottom = height;
+                    }
+                }
+                childHeightSpec = MeasureSpec.makeMeasureSpec(
+                        (int) (height * (scaleEndRow - scaleStartRow)), MeasureSpec.EXACTLY);
+                child.measure(childWidthSpec, childHeightSpec);
+            }
+
+            // Avoid overlapping rectangles.
+            // Step 1. Sort rectangles by position (top-left).
+            int visibleRectCount = 0;
+            int[] visibleRectGroup = new int[count];
+            Rect[] visibleRectArray = new Rect[count];
+            for (int i = 0; i < count; ++i) {
+                if (getChildAt(i).getVisibility() == View.VISIBLE) {
+                    visibleRectGroup[visibleRectCount] = visibleRectCount;
+                    visibleRectArray[visibleRectCount] = mRectArray[i];
+                    ++visibleRectCount;
+                }
+            }
+            Arrays.sort(visibleRectArray, 0, visibleRectCount, mRectTopLeftSorter);
+
+            // Step 2. Move down if there are overlapping rectangles.
+            for (int i = 0; i < visibleRectCount - 1; ++i) {
+                for (int j = i + 1; j < visibleRectCount; ++j) {
+                    if (Rect.intersects(visibleRectArray[i], visibleRectArray[j])) {
+                        visibleRectGroup[j] = visibleRectGroup[i];
+                        visibleRectArray[j].set(visibleRectArray[j].left,
+                                visibleRectArray[i].bottom,
+                                visibleRectArray[j].right,
+                                visibleRectArray[i].bottom + visibleRectArray[j].height());
+                    }
+                }
+            }
+
+            // Step 3. Move up if there is any overflowed rectangle.
+            for (int i = visibleRectCount - 1; i >= 0; --i) {
+                if (visibleRectArray[i].bottom > height) {
+                    int overflowedHeight = visibleRectArray[i].bottom - height;
+                    for (int j = 0; j <= i; ++j) {
+                        if (visibleRectGroup[i] == visibleRectGroup[j]) {
+                            visibleRectArray[j].set(visibleRectArray[j].left,
+                                    visibleRectArray[j].top - overflowedHeight,
+                                    visibleRectArray[j].right,
+                                    visibleRectArray[j].bottom - overflowedHeight);
+                        }
+                    }
+                }
+            }
+            setMeasuredDimension(widthSpecSize, heightSpecSize);
+        }
+
+        @Override
+        protected void onLayout(boolean changed, int l, int t, int r, int b) {
+            int paddingLeft = getPaddingLeft();
+            int paddingTop = getPaddingTop();
+            int count = getChildCount();
+            for (int i = 0; i < count; ++i) {
+                View child = getChildAt(i);
+                if (child.getVisibility() != GONE) {
+                    int childLeft = paddingLeft + mRectArray[i].left;
+                    int childTop = paddingTop + mRectArray[i].top;
+                    int childBottom = paddingLeft + mRectArray[i].bottom;
+                    int childRight = paddingTop + mRectArray[i].right;
+                    if (DEBUG) {
+                        Log.d(TAG, String.format(
+                                "child layout bottom: %d left: %d right: %d top: %d",
+                                childBottom, childLeft, childRight, childTop));
+                    }
+                    child.layout(childLeft, childTop, childRight, childBottom);
+                }
+            }
+        }
+
+        @Override
+        public void dispatchDraw(Canvas canvas) {
+            int paddingLeft = getPaddingLeft();
+            int paddingTop = getPaddingTop();
+            int count = getChildCount();
+            for (int i = 0; i < count; ++i) {
+                View child = getChildAt(i);
+                if (child.getVisibility() != GONE) {
+                    if (i >= mRectArray.length) {
+                        break;
+                    }
+                    int childLeft = paddingLeft + mRectArray[i].left;
+                    int childTop = paddingTop + mRectArray[i].top;
+                    final int saveCount = canvas.save();
+                    canvas.translate(childLeft, childTop);
+                    child.draw(canvas);
+                    canvas.restoreToCount(saveCount);
+                }
+            }
+        }
+    }
+
+    /**
+     * @hide
+     *
+     * Layout containing the safe title area that helps the closed captions look more prominent.
+     *
+     * <p>This is required by CEA-708B.
+     */
+    static class CCLayout extends ScaledLayout implements ClosedCaptionLayout {
+        private static final float SAFE_TITLE_AREA_SCALE_START_X = 0.1f;
+        private static final float SAFE_TITLE_AREA_SCALE_END_X = 0.9f;
+        private static final float SAFE_TITLE_AREA_SCALE_START_Y = 0.1f;
+        private static final float SAFE_TITLE_AREA_SCALE_END_Y = 0.9f;
+
+        private final ScaledLayout mSafeTitleAreaLayout;
+
+        public CCLayout(Context context) {
+            super(context);
+
+            mSafeTitleAreaLayout = new ScaledLayout(context);
+            addView(mSafeTitleAreaLayout, new ScaledLayout.ScaledLayoutParams(
+                    SAFE_TITLE_AREA_SCALE_START_X, SAFE_TITLE_AREA_SCALE_END_X,
+                    SAFE_TITLE_AREA_SCALE_START_Y, SAFE_TITLE_AREA_SCALE_END_Y));
+        }
+
+        public void addOrUpdateViewToSafeTitleArea(CCWindowLayout captionWindowLayout,
+                ScaledLayoutParams scaledLayoutParams) {
+            int index = mSafeTitleAreaLayout.indexOfChild(captionWindowLayout);
+            if (index < 0) {
+                mSafeTitleAreaLayout.addView(captionWindowLayout, scaledLayoutParams);
+                return;
+            }
+            mSafeTitleAreaLayout.updateViewLayout(captionWindowLayout, scaledLayoutParams);
+        }
+
+        public void removeViewFromSafeTitleArea(CCWindowLayout captionWindowLayout) {
+            mSafeTitleAreaLayout.removeView(captionWindowLayout);
+        }
+
+        public void setCaptionStyle(CaptionStyle style) {
+            final int count = mSafeTitleAreaLayout.getChildCount();
+            for (int i = 0; i < count; ++i) {
+                final CCWindowLayout windowLayout =
+                        (CCWindowLayout) mSafeTitleAreaLayout.getChildAt(i);
+                windowLayout.setCaptionStyle(style);
+            }
+        }
+
+        public void setFontScale(float fontScale) {
+            final int count = mSafeTitleAreaLayout.getChildCount();
+            for (int i = 0; i < count; ++i) {
+                final CCWindowLayout windowLayout =
+                        (CCWindowLayout) mSafeTitleAreaLayout.getChildAt(i);
+                windowLayout.setFontScale(fontScale);
+            }
+        }
+    }
+
+    /**
+     * @hide
+     *
+     * Renders the selected CC track.
+     */
+    static class CCHandler implements Handler.Callback {
+        // TODO: Remaining works
+        // CaptionTrackRenderer does not support the full spec of CEA-708. The remaining works are
+        // described in the follows.
+        // C0 Table: Backspace, FF, and HCR are not supported. The rule for P16 is not standardized
+        //           but it is handled as EUC-KR charset for Korea broadcasting.
+        // C1 Table: All the styles of windows and pens except underline, italic, pen size, and pen
+        //           offset specified in CEA-708 are ignored and this follows system wide CC
+        //           preferences for look and feel. SetPenLocation is not implemented.
+        // G2 Table: TSP, NBTSP and BLK are not supported.
+        // Text/commands: Word wrapping, fonts, row and column locking are not supported.
+
+        private static final String TAG = "CCHandler";
+        private static final boolean DEBUG = false;
+
+        private static final int TENTHS_OF_SECOND_IN_MILLIS = 100;
+
+        // According to CEA-708B, there can exist up to 8 caption windows.
+        private static final int CAPTION_WINDOWS_MAX = 8;
+        private static final int CAPTION_ALL_WINDOWS_BITMAP = 255;
+
+        private static final int MSG_DELAY_CANCEL = 1;
+        private static final int MSG_CAPTION_CLEAR = 2;
+
+        private static final long CAPTION_CLEAR_INTERVAL_MS = 60000;
+
+        private final CCLayout mCCLayout;
+        private boolean mIsDelayed = false;
+        private CCWindowLayout mCurrentWindowLayout;
+        private final CCWindowLayout[] mCaptionWindowLayouts =
+                new CCWindowLayout[CAPTION_WINDOWS_MAX];
+        private final ArrayList<Cea708CCParser.CaptionEvent> mPendingCaptionEvents
+                = new ArrayList<>();
+        private final Handler mHandler;
+
+        public CCHandler(CCLayout ccLayout) {
+            mCCLayout = ccLayout;
+            mHandler = new Handler(this);
+        }
+
+        @Override
+        public boolean handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_DELAY_CANCEL:
+                    delayCancel();
+                    return true;
+                case MSG_CAPTION_CLEAR:
+                    clearWindows(CAPTION_ALL_WINDOWS_BITMAP);
+                    return true;
+            }
+            return false;
+        }
+
+        public void processCaptionEvent(Cea708CCParser.CaptionEvent event) {
+            if (mIsDelayed) {
+                mPendingCaptionEvents.add(event);
+                return;
+            }
+            switch (event.type) {
+                case Cea708CCParser.CAPTION_EMIT_TYPE_BUFFER:
+                    sendBufferToCurrentWindow((String) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_CONTROL:
+                    sendControlToCurrentWindow((char) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_CWX:
+                    setCurrentWindowLayout((int) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_CLW:
+                    clearWindows((int) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_DSW:
+                    displayWindows((int) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_HDW:
+                    hideWindows((int) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_TGW:
+                    toggleWindows((int) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_DLW:
+                    deleteWindows((int) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_DLY:
+                    delay((int) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_DLC:
+                    delayCancel();
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_RST:
+                    reset();
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_SPA:
+                    setPenAttr((Cea708CCParser.CaptionPenAttr) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_SPC:
+                    setPenColor((Cea708CCParser.CaptionPenColor) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_SPL:
+                    setPenLocation((Cea708CCParser.CaptionPenLocation) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_SWA:
+                    setWindowAttr((Cea708CCParser.CaptionWindowAttr) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_DFX:
+                    defineWindow((Cea708CCParser.CaptionWindow) event.obj);
+                    break;
+            }
+        }
+
+        // The window related caption commands
+        private void setCurrentWindowLayout(int windowId) {
+            if (windowId < 0 || windowId >= mCaptionWindowLayouts.length) {
+                return;
+            }
+            CCWindowLayout windowLayout = mCaptionWindowLayouts[windowId];
+            if (windowLayout == null) {
+                return;
+            }
+            if (DEBUG) {
+                Log.d(TAG, "setCurrentWindowLayout to " + windowId);
+            }
+            mCurrentWindowLayout = windowLayout;
+        }
+
+        // Each bit of windowBitmap indicates a window.
+        // If a bit is set, the window id is the same as the number of the trailing zeros of the
+        // bit.
+        private ArrayList<CCWindowLayout> getWindowsFromBitmap(int windowBitmap) {
+            ArrayList<CCWindowLayout> windows = new ArrayList<>();
+            for (int i = 0; i < CAPTION_WINDOWS_MAX; ++i) {
+                if ((windowBitmap & (1 << i)) != 0) {
+                    CCWindowLayout windowLayout = mCaptionWindowLayouts[i];
+                    if (windowLayout != null) {
+                        windows.add(windowLayout);
+                    }
+                }
+            }
+            return windows;
+        }
+
+        private void clearWindows(int windowBitmap) {
+            if (windowBitmap == 0) {
+                return;
+            }
+            for (CCWindowLayout windowLayout : getWindowsFromBitmap(windowBitmap)) {
+                windowLayout.clear();
+            }
+        }
+
+        private void displayWindows(int windowBitmap) {
+            if (windowBitmap == 0) {
+                return;
+            }
+            for (CCWindowLayout windowLayout : getWindowsFromBitmap(windowBitmap)) {
+                windowLayout.show();
+            }
+        }
+
+        private void hideWindows(int windowBitmap) {
+            if (windowBitmap == 0) {
+                return;
+            }
+            for (CCWindowLayout windowLayout : getWindowsFromBitmap(windowBitmap)) {
+                windowLayout.hide();
+            }
+        }
+
+        private void toggleWindows(int windowBitmap) {
+            if (windowBitmap == 0) {
+                return;
+            }
+            for (CCWindowLayout windowLayout : getWindowsFromBitmap(windowBitmap)) {
+                if (windowLayout.isShown()) {
+                    windowLayout.hide();
+                } else {
+                    windowLayout.show();
+                }
+            }
+        }
+
+        private void deleteWindows(int windowBitmap) {
+            if (windowBitmap == 0) {
+                return;
+            }
+            for (CCWindowLayout windowLayout : getWindowsFromBitmap(windowBitmap)) {
+                windowLayout.removeFromCaptionView();
+                mCaptionWindowLayouts[windowLayout.getCaptionWindowId()] = null;
+            }
+        }
+
+        public void reset() {
+            mCurrentWindowLayout = null;
+            mIsDelayed = false;
+            mPendingCaptionEvents.clear();
+            for (int i = 0; i < CAPTION_WINDOWS_MAX; ++i) {
+                if (mCaptionWindowLayouts[i] != null) {
+                    mCaptionWindowLayouts[i].removeFromCaptionView();
+                }
+                mCaptionWindowLayouts[i] = null;
+            }
+            mCCLayout.setVisibility(View.INVISIBLE);
+            mHandler.removeMessages(MSG_CAPTION_CLEAR);
+        }
+
+        private void setWindowAttr(Cea708CCParser.CaptionWindowAttr windowAttr) {
+            if (mCurrentWindowLayout != null) {
+                mCurrentWindowLayout.setWindowAttr(windowAttr);
+            }
+        }
+
+        private void defineWindow(Cea708CCParser.CaptionWindow window) {
+            if (window == null) {
+                return;
+            }
+            int windowId = window.id;
+            if (windowId < 0 || windowId >= mCaptionWindowLayouts.length) {
+                return;
+            }
+            CCWindowLayout windowLayout = mCaptionWindowLayouts[windowId];
+            if (windowLayout == null) {
+                windowLayout = new CCWindowLayout(mCCLayout.getContext());
+            }
+            windowLayout.initWindow(mCCLayout, window);
+            mCurrentWindowLayout = mCaptionWindowLayouts[windowId] = windowLayout;
+        }
+
+        // The job related caption commands
+        private void delay(int tenthsOfSeconds) {
+            if (tenthsOfSeconds < 0 || tenthsOfSeconds > 255) {
+                return;
+            }
+            mIsDelayed = true;
+            mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_DELAY_CANCEL),
+                    tenthsOfSeconds * TENTHS_OF_SECOND_IN_MILLIS);
+        }
+
+        private void delayCancel() {
+            mIsDelayed = false;
+            processPendingBuffer();
+        }
+
+        private void processPendingBuffer() {
+            for (Cea708CCParser.CaptionEvent event : mPendingCaptionEvents) {
+                processCaptionEvent(event);
+            }
+            mPendingCaptionEvents.clear();
+        }
+
+        // The implicit write caption commands
+        private void sendControlToCurrentWindow(char control) {
+            if (mCurrentWindowLayout != null) {
+                mCurrentWindowLayout.sendControl(control);
+            }
+        }
+
+        private void sendBufferToCurrentWindow(String buffer) {
+            if (mCurrentWindowLayout != null) {
+                mCurrentWindowLayout.sendBuffer(buffer);
+                mHandler.removeMessages(MSG_CAPTION_CLEAR);
+                mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CAPTION_CLEAR),
+                        CAPTION_CLEAR_INTERVAL_MS);
+            }
+        }
+
+        // The pen related caption commands
+        private void setPenAttr(Cea708CCParser.CaptionPenAttr attr) {
+            if (mCurrentWindowLayout != null) {
+                mCurrentWindowLayout.setPenAttr(attr);
+            }
+        }
+
+        private void setPenColor(Cea708CCParser.CaptionPenColor color) {
+            if (mCurrentWindowLayout != null) {
+                mCurrentWindowLayout.setPenColor(color);
+            }
+        }
+
+        private void setPenLocation(Cea708CCParser.CaptionPenLocation location) {
+            if (mCurrentWindowLayout != null) {
+                mCurrentWindowLayout.setPenLocation(location.row, location.column);
+            }
+        }
+    }
+
+    /**
+     * @hide
+     *
+     * Layout which renders a caption window of CEA-708B. It contains a {@link TextView} that takes
+     * care of displaying the actual CC text.
+     */
+    static class CCWindowLayout extends RelativeLayout implements View.OnLayoutChangeListener {
+        private static final String TAG = "CCWindowLayout";
+
+        private static final float PROPORTION_PEN_SIZE_SMALL = .75f;
+        private static final float PROPORTION_PEN_SIZE_LARGE = 1.25f;
+
+        // The following values indicates the maximum cell number of a window.
+        private static final int ANCHOR_RELATIVE_POSITIONING_MAX = 99;
+        private static final int ANCHOR_VERTICAL_MAX = 74;
+        private static final int ANCHOR_HORIZONTAL_16_9_MAX = 209;
+        private static final int MAX_COLUMN_COUNT_16_9 = 42;
+
+        // The following values indicates a gravity of a window.
+        private static final int ANCHOR_MODE_DIVIDER = 3;
+        private static final int ANCHOR_HORIZONTAL_MODE_LEFT = 0;
+        private static final int ANCHOR_HORIZONTAL_MODE_CENTER = 1;
+        private static final int ANCHOR_HORIZONTAL_MODE_RIGHT = 2;
+        private static final int ANCHOR_VERTICAL_MODE_TOP = 0;
+        private static final int ANCHOR_VERTICAL_MODE_CENTER = 1;
+        private static final int ANCHOR_VERTICAL_MODE_BOTTOM = 2;
+
+        private CCLayout mCCLayout;
+
+        private CCView mCCView;
+        private CaptionStyle mCaptionStyle;
+        private int mRowLimit = 0;
+        private final SpannableStringBuilder mBuilder = new SpannableStringBuilder();
+        private final List<CharacterStyle> mCharacterStyles = new ArrayList<>();
+        private int mCaptionWindowId;
+        private int mRow = -1;
+        private float mFontScale;
+        private float mTextSize;
+        private String mWidestChar;
+        private int mLastCaptionLayoutWidth;
+        private int mLastCaptionLayoutHeight;
+
+        public CCWindowLayout(Context context) {
+            this(context, null);
+        }
+
+        public CCWindowLayout(Context context, AttributeSet attrs) {
+            this(context, attrs, 0);
+        }
+
+        public CCWindowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+            this(context, attrs, defStyleAttr, 0);
+        }
+
+        public CCWindowLayout(Context context, AttributeSet attrs, int defStyleAttr,
+                int defStyleRes) {
+            super(context, attrs, defStyleAttr, defStyleRes);
+
+            // Add a subtitle view to the layout.
+            mCCView = new CCView(context);
+            LayoutParams params = new RelativeLayout.LayoutParams(
+                    ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+            addView(mCCView, params);
+
+            // Set the system wide CC preferences to the subtitle view.
+            CaptioningManager captioningManager =
+                    (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
+            mFontScale = captioningManager.getFontScale();
+            setCaptionStyle(captioningManager.getUserStyle());
+            mCCView.setText("");
+            updateWidestChar();
+        }
+
+        public void setCaptionStyle(CaptionStyle style) {
+            mCaptionStyle = style;
+            mCCView.setCaptionStyle(style);
+        }
+
+        public void setFontScale(float fontScale) {
+            mFontScale = fontScale;
+            updateTextSize();
+        }
+
+        public int getCaptionWindowId() {
+            return mCaptionWindowId;
+        }
+
+        public void setCaptionWindowId(int captionWindowId) {
+            mCaptionWindowId = captionWindowId;
+        }
+
+        public void clear() {
+            clearText();
+            hide();
+        }
+
+        public void show() {
+            setVisibility(View.VISIBLE);
+            requestLayout();
+        }
+
+        public void hide() {
+            setVisibility(View.INVISIBLE);
+            requestLayout();
+        }
+
+        public void setPenAttr(Cea708CCParser.CaptionPenAttr penAttr) {
+            mCharacterStyles.clear();
+            if (penAttr.italic) {
+                mCharacterStyles.add(new StyleSpan(Typeface.ITALIC));
+            }
+            if (penAttr.underline) {
+                mCharacterStyles.add(new UnderlineSpan());
+            }
+            switch (penAttr.penSize) {
+                case Cea708CCParser.CaptionPenAttr.PEN_SIZE_SMALL:
+                    mCharacterStyles.add(new RelativeSizeSpan(PROPORTION_PEN_SIZE_SMALL));
+                    break;
+                case Cea708CCParser.CaptionPenAttr.PEN_SIZE_LARGE:
+                    mCharacterStyles.add(new RelativeSizeSpan(PROPORTION_PEN_SIZE_LARGE));
+                    break;
+            }
+            switch (penAttr.penOffset) {
+                case Cea708CCParser.CaptionPenAttr.OFFSET_SUBSCRIPT:
+                    mCharacterStyles.add(new SubscriptSpan());
+                    break;
+                case Cea708CCParser.CaptionPenAttr.OFFSET_SUPERSCRIPT:
+                    mCharacterStyles.add(new SuperscriptSpan());
+                    break;
+            }
+        }
+
+        public void setPenColor(Cea708CCParser.CaptionPenColor penColor) {
+            // TODO: apply pen colors or skip this and use the style of system wide CC style as is.
+        }
+
+        public void setPenLocation(int row, int column) {
+            // TODO: change the location of pen based on row and column both.
+            if (mRow >= 0) {
+                for (int r = mRow; r < row; ++r) {
+                    appendText("\n");
+                }
+            }
+            mRow = row;
+        }
+
+        public void setWindowAttr(Cea708CCParser.CaptionWindowAttr windowAttr) {
+            // TODO: apply window attrs or skip this and use the style of system wide CC style as
+            // is.
+        }
+
+        public void sendBuffer(String buffer) {
+            appendText(buffer);
+        }
+
+        public void sendControl(char control) {
+            // TODO: there are a bunch of ASCII-style control codes.
+        }
+
+        /**
+         * This method places the window on a given CaptionLayout along with the anchor of the
+         * window.
+         * <p>
+         * According to CEA-708B, the anchor id indicates the gravity of the window as the follows.
+         * For example, A value 7 of a anchor id says that a window is align with its parent bottom
+         * and is located at the center horizontally of its parent.
+         * </p>
+         * <h4>Anchor id and the gravity of a window</h4>
+         * <table>
+         *     <tr>
+         *         <th>GRAVITY</th>
+         *         <th>LEFT</th>
+         *         <th>CENTER_HORIZONTAL</th>
+         *         <th>RIGHT</th>
+         *     </tr>
+         *     <tr>
+         *         <th>TOP</th>
+         *         <td>0</td>
+         *         <td>1</td>
+         *         <td>2</td>
+         *     </tr>
+         *     <tr>
+         *         <th>CENTER_VERTICAL</th>
+         *         <td>3</td>
+         *         <td>4</td>
+         *         <td>5</td>
+         *     </tr>
+         *     <tr>
+         *         <th>BOTTOM</th>
+         *         <td>6</td>
+         *         <td>7</td>
+         *         <td>8</td>
+         *     </tr>
+         * </table>
+         * <p>
+         * In order to handle the gravity of a window, there are two steps. First, set the size of
+         * the window. Since the window will be positioned at ScaledLayout, the size factors are
+         * determined in a ratio. Second, set the gravity of the window. CaptionWindowLayout is
+         * inherited from RelativeLayout. Hence, we could set the gravity of its child view,
+         * SubtitleView.
+         * </p>
+         * <p>
+         * The gravity of the window is also related to its size. When it should be pushed to a one
+         * of the end of the window, like LEFT, RIGHT, TOP or BOTTOM, the anchor point should be a
+         * boundary of the window. When it should be pushed in the horizontal/vertical center of its
+         * container, the horizontal/vertical center point of the window should be the same as the
+         * anchor point.
+         * </p>
+         *
+         * @param ccLayout a given CaptionLayout, which contains a safe title area.
+         * @param captionWindow a given CaptionWindow, which stores the construction info of the
+         *                      window.
+         */
+        public void initWindow(CCLayout ccLayout, Cea708CCParser.CaptionWindow captionWindow) {
+            if (mCCLayout != ccLayout) {
+                if (mCCLayout != null) {
+                    mCCLayout.removeOnLayoutChangeListener(this);
+                }
+                mCCLayout = ccLayout;
+                mCCLayout.addOnLayoutChangeListener(this);
+                updateWidestChar();
+            }
+
+            // Both anchor vertical and horizontal indicates the position cell number of the window.
+            float scaleRow = (float) captionWindow.anchorVertical /
+                    (captionWindow.relativePositioning
+                            ? ANCHOR_RELATIVE_POSITIONING_MAX : ANCHOR_VERTICAL_MAX);
+
+            // Assumes it has a wide aspect ratio track.
+            float scaleCol = (float) captionWindow.anchorHorizontal /
+                    (captionWindow.relativePositioning ? ANCHOR_RELATIVE_POSITIONING_MAX
+                            : ANCHOR_HORIZONTAL_16_9_MAX);
+
+            // The range of scaleRow/Col need to be verified to be in [0, 1].
+            // Otherwise a RuntimeException will be raised in ScaledLayout.
+            if (scaleRow < 0 || scaleRow > 1) {
+                Log.i(TAG, "The vertical position of the anchor point should be at the range of 0 "
+                        + "and 1 but " + scaleRow);
+                scaleRow = Math.max(0, Math.min(scaleRow, 1));
+            }
+            if (scaleCol < 0 || scaleCol > 1) {
+                Log.i(TAG, "The horizontal position of the anchor point should be at the range of 0"
+                        + " and 1 but " + scaleCol);
+                scaleCol = Math.max(0, Math.min(scaleCol, 1));
+            }
+            int gravity = Gravity.CENTER;
+            int horizontalMode = captionWindow.anchorId % ANCHOR_MODE_DIVIDER;
+            int verticalMode = captionWindow.anchorId / ANCHOR_MODE_DIVIDER;
+            float scaleStartRow = 0;
+            float scaleEndRow = 1;
+            float scaleStartCol = 0;
+            float scaleEndCol = 1;
+            switch (horizontalMode) {
+                case ANCHOR_HORIZONTAL_MODE_LEFT:
+                    gravity = Gravity.LEFT;
+                    mCCView.setAlignment(Alignment.ALIGN_NORMAL);
+                    scaleStartCol = scaleCol;
+                    break;
+                case ANCHOR_HORIZONTAL_MODE_CENTER:
+                    float gap = Math.min(1 - scaleCol, scaleCol);
+
+                    // Since all TV sets use left text alignment instead of center text alignment
+                    // for this case, we follow the industry convention if possible.
+                    int columnCount = captionWindow.columnCount + 1;
+                    columnCount = Math.min(getScreenColumnCount(), columnCount);
+                    StringBuilder widestTextBuilder = new StringBuilder();
+                    for (int i = 0; i < columnCount; ++i) {
+                        widestTextBuilder.append(mWidestChar);
+                    }
+                    Paint paint = new Paint();
+                    paint.setTypeface(mCaptionStyle.getTypeface());
+                    paint.setTextSize(mTextSize);
+                    float maxWindowWidth = paint.measureText(widestTextBuilder.toString());
+                    float halfMaxWidthScale = mCCLayout.getWidth() > 0
+                            ? maxWindowWidth / 2.0f / (mCCLayout.getWidth() * 0.8f) : 0.0f;
+                    if (halfMaxWidthScale > 0f && halfMaxWidthScale < scaleCol) {
+                        // Calculate the expected max window size based on the column count of the
+                        // caption window multiplied by average alphabets char width, then align the
+                        // left side of the window with the left side of the expected max window.
+                        gravity = Gravity.LEFT;
+                        mCCView.setAlignment(Alignment.ALIGN_NORMAL);
+                        scaleStartCol = scaleCol - halfMaxWidthScale;
+                        scaleEndCol = 1.0f;
+                    } else {
+                        // The gap will be the minimum distance value of the distances from both
+                        // horizontal end points to the anchor point.
+                        // If scaleCol <= 0.5, the range of scaleCol is [0, the anchor point * 2].
+                        // If scaleCol > 0.5, the range of scaleCol is
+                        // [(1 - the anchor point) * 2, 1].
+                        // The anchor point is located at the horizontal center of the window in
+                        // both cases.
+                        gravity = Gravity.CENTER_HORIZONTAL;
+                        mCCView.setAlignment(Alignment.ALIGN_CENTER);
+                        scaleStartCol = scaleCol - gap;
+                        scaleEndCol = scaleCol + gap;
+                    }
+                    break;
+                case ANCHOR_HORIZONTAL_MODE_RIGHT:
+                    gravity = Gravity.RIGHT;
+                    mCCView.setAlignment(Alignment.ALIGN_RIGHT);
+                    scaleEndCol = scaleCol;
+                    break;
+            }
+            switch (verticalMode) {
+                case ANCHOR_VERTICAL_MODE_TOP:
+                    gravity |= Gravity.TOP;
+                    scaleStartRow = scaleRow;
+                    break;
+                case ANCHOR_VERTICAL_MODE_CENTER:
+                    gravity |= Gravity.CENTER_VERTICAL;
+
+                    // See the above comment.
+                    float gap = Math.min(1 - scaleRow, scaleRow);
+                    scaleStartRow = scaleRow - gap;
+                    scaleEndRow = scaleRow + gap;
+                    break;
+                case ANCHOR_VERTICAL_MODE_BOTTOM:
+                    gravity |= Gravity.BOTTOM;
+                    scaleEndRow = scaleRow;
+                    break;
+            }
+            mCCLayout.addOrUpdateViewToSafeTitleArea(this, new ScaledLayout
+                    .ScaledLayoutParams(scaleStartRow, scaleEndRow, scaleStartCol, scaleEndCol));
+            setCaptionWindowId(captionWindow.id);
+            setRowLimit(captionWindow.rowCount);
+            setGravity(gravity);
+            if (captionWindow.visible) {
+                show();
+            } else {
+                hide();
+            }
+        }
+
+        @Override
+        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
+                int oldTop, int oldRight, int oldBottom) {
+            int width = right - left;
+            int height = bottom - top;
+            if (width != mLastCaptionLayoutWidth || height != mLastCaptionLayoutHeight) {
+                mLastCaptionLayoutWidth = width;
+                mLastCaptionLayoutHeight = height;
+                updateTextSize();
+            }
+        }
+
+        private void updateWidestChar() {
+            Paint paint = new Paint();
+            paint.setTypeface(mCaptionStyle.getTypeface());
+            Charset latin1 = Charset.forName("ISO-8859-1");
+            float widestCharWidth = 0f;
+            for (int i = 0; i < 256; ++i) {
+                String ch = new String(new byte[]{(byte) i}, latin1);
+                float charWidth = paint.measureText(ch);
+                if (widestCharWidth < charWidth) {
+                    widestCharWidth = charWidth;
+                    mWidestChar = ch;
+                }
+            }
+            updateTextSize();
+        }
+
+        private void updateTextSize() {
+            if (mCCLayout == null) return;
+
+            // Calculate text size based on the max window size.
+            StringBuilder widestTextBuilder = new StringBuilder();
+            int screenColumnCount = getScreenColumnCount();
+            for (int i = 0; i < screenColumnCount; ++i) {
+                widestTextBuilder.append(mWidestChar);
+            }
+            String widestText = widestTextBuilder.toString();
+            Paint paint = new Paint();
+            paint.setTypeface(mCaptionStyle.getTypeface());
+            float startFontSize = 0f;
+            float endFontSize = 255f;
+            while (startFontSize < endFontSize) {
+                float testTextSize = (startFontSize + endFontSize) / 2f;
+                paint.setTextSize(testTextSize);
+                float width = paint.measureText(widestText);
+                if (mCCLayout.getWidth() * 0.8f > width) {
+                    startFontSize = testTextSize + 0.01f;
+                } else {
+                    endFontSize = testTextSize - 0.01f;
+                }
+            }
+            mTextSize = endFontSize * mFontScale;
+            mCCView.setTextSize(mTextSize);
+        }
+
+        private int getScreenColumnCount() {
+            // Assume it has a wide aspect ratio track.
+            return MAX_COLUMN_COUNT_16_9;
+        }
+
+        public void removeFromCaptionView() {
+            if (mCCLayout != null) {
+                mCCLayout.removeViewFromSafeTitleArea(this);
+                mCCLayout.removeOnLayoutChangeListener(this);
+                mCCLayout = null;
+            }
+        }
+
+        public void setText(String text) {
+            updateText(text, false);
+        }
+
+        public void appendText(String text) {
+            updateText(text, true);
+        }
+
+        public void clearText() {
+            mBuilder.clear();
+            mCCView.setText("");
+        }
+
+        private void updateText(String text, boolean appended) {
+            if (!appended) {
+                mBuilder.clear();
+            }
+            if (text != null && text.length() > 0) {
+                int length = mBuilder.length();
+                mBuilder.append(text);
+                for (CharacterStyle characterStyle : mCharacterStyles) {
+                    mBuilder.setSpan(characterStyle, length, mBuilder.length(),
+                            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+                }
+            }
+            String[] lines = TextUtils.split(mBuilder.toString(), "\n");
+
+            // Truncate text not to exceed the row limit.
+            // Plus one here since the range of the rows is [0, mRowLimit].
+            String truncatedText = TextUtils.join("\n", Arrays.copyOfRange(
+                    lines, Math.max(0, lines.length - (mRowLimit + 1)), lines.length));
+            mBuilder.delete(0, mBuilder.length() - truncatedText.length());
+
+            // Trim the buffer first then set text to CCView.
+            int start = 0, last = mBuilder.length() - 1;
+            int end = last;
+            while ((start <= end) && (mBuilder.charAt(start) <= ' ')) {
+                ++start;
+            }
+            while ((end >= start) && (mBuilder.charAt(end) <= ' ')) {
+                --end;
+            }
+            if (start == 0 && end == last) {
+                mCCView.setText(mBuilder);
+            } else {
+                SpannableStringBuilder trim = new SpannableStringBuilder();
+                trim.append(mBuilder);
+                if (end < last) {
+                    trim.delete(end + 1, last + 1);
+                }
+                if (start > 0) {
+                    trim.delete(0, start);
+                }
+                mCCView.setText(trim);
+            }
+        }
+
+        public void setRowLimit(int rowLimit) {
+            if (rowLimit < 0) {
+                throw new IllegalArgumentException("A rowLimit should have a positive number");
+            }
+            mRowLimit = rowLimit;
+        }
+    }
+
+    /** @hide */
+    static class CCView extends SubtitleView {
+        private static final CaptionStyle DEFAULT_CAPTION_STYLE = CaptionStyle.DEFAULT;
+
+        public CCView(Context context) {
+            this(context, null);
+        }
+
+        public CCView(Context context, AttributeSet attrs) {
+            this(context, attrs, 0);
+        }
+
+        public CCView(Context context, AttributeSet attrs, int defStyleAttr) {
+            this(context, attrs, defStyleAttr, 0);
+        }
+
+        public CCView(Context context, AttributeSet attrs, int defStyleAttr,
+                int defStyleRes) {
+            super(context, attrs, defStyleAttr, defStyleRes);
+        }
+
+        public void setCaptionStyle(CaptionStyle style) {
+            setForegroundColor(style.hasForegroundColor()
+                    ? style.foregroundColor : DEFAULT_CAPTION_STYLE.foregroundColor);
+            setBackgroundColor(style.hasBackgroundColor()
+                    ? style.backgroundColor : DEFAULT_CAPTION_STYLE.backgroundColor);
+            setEdgeType(style.hasEdgeType()
+                    ? style.edgeType : DEFAULT_CAPTION_STYLE.edgeType);
+            setEdgeColor(style.hasEdgeColor()
+                    ? style.edgeColor : DEFAULT_CAPTION_STYLE.edgeColor);
+            setTypeface(style.getTypeface());
+        }
+    }
+}
diff --git a/media/java/android/media/ClosedCaptionRenderer.java b/media/java/android/media/ClosedCaptionRenderer.java
index 8403c1c..cc7722a 100644
--- a/media/java/android/media/ClosedCaptionRenderer.java
+++ b/media/java/android/media/ClosedCaptionRenderer.java
@@ -23,12 +23,9 @@
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.Typeface;
-import android.os.Parcel;
-import android.text.ParcelableSpan;
 import android.text.Spannable;
 import android.text.SpannableStringBuilder;
 import android.text.TextPaint;
-import android.text.TextUtils;
 import android.text.style.CharacterStyle;
 import android.text.style.StyleSpan;
 import android.text.style.UnderlineSpan;
@@ -52,7 +49,7 @@
 /** @hide */
 public class ClosedCaptionRenderer extends SubtitleController.Renderer {
     private final Context mContext;
-    private ClosedCaptionWidget mRenderingWidget;
+    private Cea608CCWidget mCCWidget;
 
     public ClosedCaptionRenderer(Context context) {
         mContext = context;
@@ -61,31 +58,35 @@
     @Override
     public boolean supports(MediaFormat format) {
         if (format.containsKey(MediaFormat.KEY_MIME)) {
-            return format.getString(MediaFormat.KEY_MIME).equals(
-                    MediaPlayer.MEDIA_MIMETYPE_TEXT_CEA_608);
+            String mimeType = format.getString(MediaFormat.KEY_MIME);
+            return MediaPlayer.MEDIA_MIMETYPE_TEXT_CEA_608.equals(mimeType);
         }
         return false;
     }
 
     @Override
     public SubtitleTrack createTrack(MediaFormat format) {
-        if (mRenderingWidget == null) {
-            mRenderingWidget = new ClosedCaptionWidget(mContext);
+        String mimeType = format.getString(MediaFormat.KEY_MIME);
+        if (MediaPlayer.MEDIA_MIMETYPE_TEXT_CEA_608.equals(mimeType)) {
+            if (mCCWidget == null) {
+                mCCWidget = new Cea608CCWidget(mContext);
+            }
+            return new Cea608CaptionTrack(mCCWidget, format);
         }
-        return new ClosedCaptionTrack(mRenderingWidget, format);
+        throw new RuntimeException("No matching format: " + format.toString());
     }
 }
 
 /** @hide */
-class ClosedCaptionTrack extends SubtitleTrack {
-    private final ClosedCaptionWidget mRenderingWidget;
-    private final CCParser mCCParser;
+class Cea608CaptionTrack extends SubtitleTrack {
+    private final Cea608CCParser mCCParser;
+    private final Cea608CCWidget mRenderingWidget;
 
-    ClosedCaptionTrack(ClosedCaptionWidget renderingWidget, MediaFormat format) {
+    Cea608CaptionTrack(Cea608CCWidget renderingWidget, MediaFormat format) {
         super(format);
 
         mRenderingWidget = renderingWidget;
-        mCCParser = new CCParser(renderingWidget);
+        mCCParser = new Cea608CCParser(mRenderingWidget);
     }
 
     @Override
@@ -105,6 +106,149 @@
 }
 
 /**
+ * Abstract widget class to render a closed caption track.
+ *
+ * @hide
+ */
+abstract class ClosedCaptionWidget extends ViewGroup implements SubtitleTrack.RenderingWidget {
+
+    /** @hide */
+    interface ClosedCaptionLayout {
+        void setCaptionStyle(CaptionStyle captionStyle);
+        void setFontScale(float scale);
+    }
+
+    private static final CaptionStyle DEFAULT_CAPTION_STYLE = CaptionStyle.DEFAULT;
+
+    /** Captioning manager, used to obtain and track caption properties. */
+    private final CaptioningManager mManager;
+
+    /** Current caption style. */
+    protected CaptionStyle mCaptionStyle;
+
+    /** Callback for rendering changes. */
+    protected OnChangedListener mListener;
+
+    /** Concrete layout of CC. */
+    protected ClosedCaptionLayout mClosedCaptionLayout;
+
+    /** Whether a caption style change listener is registered. */
+    private boolean mHasChangeListener;
+
+    public ClosedCaptionWidget(Context context) {
+        this(context, null);
+    }
+
+    public ClosedCaptionWidget(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public ClosedCaptionWidget(Context context, AttributeSet attrs, int defStyle) {
+        this(context, attrs, defStyle, 0);
+    }
+
+    public ClosedCaptionWidget(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        // Cannot render text over video when layer type is hardware.
+        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+
+        mManager = (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
+        mCaptionStyle = DEFAULT_CAPTION_STYLE.applyStyle(mManager.getUserStyle());
+
+        mClosedCaptionLayout = createCaptionLayout(context);
+        mClosedCaptionLayout.setCaptionStyle(mCaptionStyle);
+        mClosedCaptionLayout.setFontScale(mManager.getFontScale());
+        addView((ViewGroup) mClosedCaptionLayout, LayoutParams.MATCH_PARENT,
+                LayoutParams.MATCH_PARENT);
+
+        requestLayout();
+    }
+
+    public abstract ClosedCaptionLayout createCaptionLayout(Context context);
+
+    @Override
+    public void setOnChangedListener(OnChangedListener listener) {
+        mListener = listener;
+    }
+
+    @Override
+    public void setSize(int width, int height) {
+        final int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
+        final int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
+
+        measure(widthSpec, heightSpec);
+        layout(0, 0, width, height);
+    }
+
+    @Override
+    public void setVisible(boolean visible) {
+        if (visible) {
+            setVisibility(View.VISIBLE);
+        } else {
+            setVisibility(View.GONE);
+        }
+
+        manageChangeListener();
+    }
+
+    @Override
+    public void onAttachedToWindow() {
+        super.onAttachedToWindow();
+
+        manageChangeListener();
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+
+        manageChangeListener();
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        ((ViewGroup) mClosedCaptionLayout).measure(widthMeasureSpec, heightMeasureSpec);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        ((ViewGroup) mClosedCaptionLayout).layout(l, t, r, b);
+    }
+
+    /**
+     * Manages whether this renderer is listening for caption style changes.
+     */
+    private final CaptioningChangeListener mCaptioningListener = new CaptioningChangeListener() {
+        @Override
+        public void onUserStyleChanged(CaptionStyle userStyle) {
+            mCaptionStyle = DEFAULT_CAPTION_STYLE.applyStyle(userStyle);
+            mClosedCaptionLayout.setCaptionStyle(mCaptionStyle);
+        }
+
+        @Override
+        public void onFontScaleChanged(float fontScale) {
+            mClosedCaptionLayout.setFontScale(fontScale);
+        }
+    };
+
+    private void manageChangeListener() {
+        final boolean needsListener = isAttachedToWindow() && getVisibility() == View.VISIBLE;
+        if (mHasChangeListener != needsListener) {
+            mHasChangeListener = needsListener;
+
+            if (needsListener) {
+                mManager.addCaptioningChangeListener(mCaptioningListener);
+            } else {
+                mManager.removeCaptioningChangeListener(mCaptioningListener);
+            }
+        }
+    }
+}
+
+/**
  * @hide
  *
  * CCParser processes CEA-608 closed caption data.
@@ -113,11 +257,11 @@
  * display change with styled text for rendering.
  *
  */
-class CCParser {
+class Cea608CCParser {
     public static final int MAX_ROWS = 15;
     public static final int MAX_COLS = 32;
 
-    private static final String TAG = "CCParser";
+    private static final String TAG = "Cea608CCParser";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private static final int INVALID = -1;
@@ -160,11 +304,11 @@
     private CCMemory mNonDisplay = new CCMemory();
     private CCMemory mTextMem = new CCMemory();
 
-    CCParser(DisplayListener listener) {
+    Cea608CCParser(DisplayListener listener) {
         mListener = listener;
     }
 
-    void parse(byte[] data) {
+    public void parse(byte[] data) {
         CCData[] ccData = CCData.fromByteArray(data);
 
         for (int i = 0; i < ccData.length; i++) {
@@ -184,8 +328,8 @@
     }
 
     interface DisplayListener {
-        public void onDisplayChanged(SpannableStringBuilder[] styledTexts);
-        public CaptionStyle getCaptionStyle();
+        void onDisplayChanged(SpannableStringBuilder[] styledTexts);
+        CaptionStyle getCaptionStyle();
     }
 
     private CCMemory getMemory() {
@@ -480,6 +624,33 @@
         }
     }
 
+    /**
+     * Mutable version of BackgroundSpan to facilitate text rendering with edge styles.
+     *
+     * @hide
+     */
+    public static class MutableBackgroundColorSpan extends CharacterStyle
+            implements UpdateAppearance {
+        private int mColor;
+
+        public MutableBackgroundColorSpan(int color) {
+            mColor = color;
+        }
+
+        public void setBackgroundColor(int color) {
+            mColor = color;
+        }
+
+        public int getBackgroundColor() {
+            return mColor;
+        }
+
+        @Override
+        public void updateDrawState(TextPaint ds) {
+            ds.bgColor = mColor;
+        }
+    }
+
     /* CCLineBuilder keeps track of displayable chars, as well as
      * MidRow styles and PACs, for a single line of CC memory.
      *
@@ -682,8 +853,7 @@
         }
 
         SpannableStringBuilder[] getStyledText(CaptionStyle captionStyle) {
-            ArrayList<SpannableStringBuilder> rows =
-                    new ArrayList<SpannableStringBuilder>(MAX_ROWS);
+            ArrayList<SpannableStringBuilder> rows = new ArrayList<>(MAX_ROWS);
             for (int i = 1; i <= MAX_ROWS; i++) {
                 rows.add(mLines[i] != null ?
                         mLines[i].getStyledText(captionStyle) : null);
@@ -1044,127 +1214,39 @@
 }
 
 /**
- * Mutable version of BackgroundSpan to facilitate text rendering with edge
- * styles.
- *
- * @hide
- */
-class MutableBackgroundColorSpan extends CharacterStyle implements UpdateAppearance {
-    private int mColor;
-
-    public MutableBackgroundColorSpan(int color) {
-        mColor = color;
-    }
-
-    public void setBackgroundColor(int color) {
-        mColor = color;
-    }
-
-    public int getBackgroundColor() {
-        return mColor;
-    }
-
-    @Override
-    public void updateDrawState(TextPaint ds) {
-        ds.bgColor = mColor;
-    }
-}
-
-/**
  * Widget capable of rendering CEA-608 closed captions.
  *
  * @hide
  */
-class ClosedCaptionWidget extends ViewGroup implements
-        SubtitleTrack.RenderingWidget,
-        CCParser.DisplayListener {
-    private static final String TAG = "ClosedCaptionWidget";
-
+class Cea608CCWidget extends ClosedCaptionWidget implements Cea608CCParser.DisplayListener {
     private static final Rect mTextBounds = new Rect();
     private static final String mDummyText = "1234567890123456789012345678901234";
-    private static final CaptionStyle DEFAULT_CAPTION_STYLE = CaptionStyle.DEFAULT;
 
-    /** Captioning manager, used to obtain and track caption properties. */
-    private final CaptioningManager mManager;
-
-    /** Callback for rendering changes. */
-    private OnChangedListener mListener;
-
-    /** Current caption style. */
-    private CaptionStyle mCaptionStyle;
-
-    /* Closed caption layout. */
-    private CCLayout mClosedCaptionLayout;
-
-    /** Whether a caption style change listener is registered. */
-    private boolean mHasChangeListener;
-
-    public ClosedCaptionWidget(Context context) {
+    public Cea608CCWidget(Context context) {
         this(context, null);
     }
 
-    public ClosedCaptionWidget(Context context, AttributeSet attrs) {
-        this(context, null, 0);
+    public Cea608CCWidget(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
     }
 
-    public ClosedCaptionWidget(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public Cea608CCWidget(Context context, AttributeSet attrs, int defStyle) {
+        this(context, attrs, defStyle, 0);
+    }
 
-        // Cannot render text over video when layer type is hardware.
-        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
-
-        mManager = (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
-        mCaptionStyle = DEFAULT_CAPTION_STYLE.applyStyle(mManager.getUserStyle());
-
-        mClosedCaptionLayout = new CCLayout(context);
-        mClosedCaptionLayout.setCaptionStyle(mCaptionStyle);
-        addView(mClosedCaptionLayout, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
-
-        requestLayout();
+    public Cea608CCWidget(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
 
     @Override
-    public void setOnChangedListener(OnChangedListener listener) {
-        mListener = listener;
-    }
-
-    @Override
-    public void setSize(int width, int height) {
-        final int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
-        final int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
-
-        measure(widthSpec, heightSpec);
-        layout(0, 0, width, height);
-    }
-
-    @Override
-    public void setVisible(boolean visible) {
-        if (visible) {
-            setVisibility(View.VISIBLE);
-        } else {
-            setVisibility(View.GONE);
-        }
-
-        manageChangeListener();
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-        super.onAttachedToWindow();
-
-        manageChangeListener();
-    }
-
-    @Override
-    public void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-
-        manageChangeListener();
+    public ClosedCaptionLayout createCaptionLayout(Context context) {
+        return new CCLayout(context);
     }
 
     @Override
     public void onDisplayChanged(SpannableStringBuilder[] styledTexts) {
-        mClosedCaptionLayout.update(styledTexts);
+        ((CCLayout) mClosedCaptionLayout).update(styledTexts);
 
         if (mListener != null) {
             mListener.onChanged(this);
@@ -1176,41 +1258,6 @@
         return mCaptionStyle;
     }
 
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        mClosedCaptionLayout.measure(widthMeasureSpec, heightMeasureSpec);
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        mClosedCaptionLayout.layout(l, t, r, b);
-    }
-
-    /**
-     * Manages whether this renderer is listening for caption style changes.
-     */
-    private final CaptioningChangeListener mCaptioningListener = new CaptioningChangeListener() {
-        @Override
-        public void onUserStyleChanged(CaptionStyle userStyle) {
-            mCaptionStyle = DEFAULT_CAPTION_STYLE.applyStyle(userStyle);
-            mClosedCaptionLayout.setCaptionStyle(mCaptionStyle);
-        }
-    };
-
-    private void manageChangeListener() {
-        final boolean needsListener = isAttachedToWindow() && getVisibility() == View.VISIBLE;
-        if (mHasChangeListener != needsListener) {
-            mHasChangeListener = needsListener;
-
-            if (needsListener) {
-                mManager.addCaptioningChangeListener(mCaptioningListener);
-            } else {
-                mManager.removeCaptioningChangeListener(mCaptioningListener);
-            }
-        }
-    }
-
     private static class CCLineBox extends TextView {
         private static final float FONT_PADDING_RATIO = 0.75f;
         private static final float EDGE_OUTLINE_RATIO = 0.1f;
@@ -1260,8 +1307,7 @@
 
         @Override
         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-            float fontSize = MeasureSpec.getSize(heightMeasureSpec)
-                    * FONT_PADDING_RATIO;
+            float fontSize = MeasureSpec.getSize(heightMeasureSpec) * FONT_PADDING_RATIO;
             setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize);
 
             mOutlineWidth = EDGE_OUTLINE_RATIO * fontSize + 1.0f;
@@ -1358,8 +1404,8 @@
             CharSequence text = getText();
             if (text instanceof Spannable) {
                 Spannable spannable = (Spannable) text;
-                MutableBackgroundColorSpan[] bgSpans = spannable.getSpans(
-                        0, spannable.length(), MutableBackgroundColorSpan.class);
+                Cea608CCParser.MutableBackgroundColorSpan[] bgSpans = spannable.getSpans(
+                        0, spannable.length(), Cea608CCParser.MutableBackgroundColorSpan.class);
                 for (int i = 0; i < bgSpans.length; i++) {
                     bgSpans[i].setBackgroundColor(color);
                 }
@@ -1367,8 +1413,8 @@
         }
     }
 
-    private static class CCLayout extends LinearLayout {
-        private static final int MAX_ROWS = CCParser.MAX_ROWS;
+    private static class CCLayout extends LinearLayout implements ClosedCaptionLayout {
+        private static final int MAX_ROWS = Cea608CCParser.MAX_ROWS;
         private static final float SAFE_AREA_RATIO = 0.9f;
 
         private final CCLineBox[] mLineBoxes = new CCLineBox[MAX_ROWS];
@@ -1383,12 +1429,18 @@
             }
         }
 
-        void setCaptionStyle(CaptionStyle captionStyle) {
+        @Override
+        public void setCaptionStyle(CaptionStyle captionStyle) {
             for (int i = 0; i < MAX_ROWS; i++) {
                 mLineBoxes[i].setCaptionStyle(captionStyle);
             }
         }
 
+        @Override
+        public void setFontScale(float fontScale) {
+            // Ignores the font scale changes of the system wide CC preference.
+        }
+
         void update(SpannableStringBuilder[] textBuffer) {
             for (int i = 0; i < MAX_ROWS; i++) {
                 if (textBuffer[i] != null) {
@@ -1455,4 +1507,4 @@
             }
         }
     }
-};
+}
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index b2fa0ac..abdf220 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -107,6 +107,7 @@
     public static final String MIMETYPE_AUDIO_MSGSM = "audio/gsm";
     public static final String MIMETYPE_AUDIO_AC3 = "audio/ac3";
     public static final String MIMETYPE_AUDIO_EAC3 = "audio/eac3";
+    public static final String MIMETYPE_VIDEO_DOLBY_VISION = "video/dolby-vision";
 
     /**
      * MIME type for WebVTT subtitle data.
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index f5b7a2e..26e466e 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -2127,6 +2127,12 @@
      */
     public static final String MEDIA_MIMETYPE_TEXT_CEA_608 = "text/cea-608";
 
+    /**
+     * MIME type for CEA-708 closed caption data.
+     * @hide
+     */
+    public static final String MEDIA_MIMETYPE_TEXT_CEA_708 = "text/cea-708";
+
     /*
      * A helper function to check if the mime type is supported by media framework.
      */
diff --git a/packages/DocumentsUI/res/values/strings.xml b/packages/DocumentsUI/res/values/strings.xml
index 016657e..05c43b2 100644
--- a/packages/DocumentsUI/res/values/strings.xml
+++ b/packages/DocumentsUI/res/values/strings.xml
@@ -87,7 +87,7 @@
     <!-- Button label that hides the error bar [CHAR LIMIT=24] -->
     <string name="button_dismiss">Dismiss</string>
     <string name="button_retry">Try Again</string>
-    
+
     <!-- Mode that sorts documents by their display name alphabetically [CHAR LIMIT=24] -->
     <string name="sort_name">By name</string>
     <!-- Mode that sorts documents by their last modified time in descending order; most recent first [CHAR LIMIT=24] -->
@@ -158,6 +158,8 @@
     <string name="copy_preparing">Preparing for copy\u2026</string>
     <!-- Text shown on the notification while DocumentsUI performs setup in preparation for moving files [CHAR LIMIT=32] -->
     <string name="move_preparing">Preparing for move\u2026</string>
+    <!-- Text shown on the notification while DocumentsUI performs setup in preparation for deleting files [CHAR LIMIT=32] -->
+    <string name="delete_preparing">Preparing for delete\u2026</string>
     <!-- Title of the copy error notification [CHAR LIMIT=48] -->
     <plurals name="copy_error_notification_title">
         <item quantity="one">Couldn\'t copy <xliff:g id="count" example="1">%1$d</xliff:g> file</item>
@@ -168,6 +170,11 @@
         <item quantity="one">Couldn\'t move <xliff:g id="count" example="1">%1$d</xliff:g> file</item>
         <item quantity="other">Couldn\'t move <xliff:g id="count" example="2">%1$d</xliff:g> files</item>
     </plurals>
+    <!-- Title of the delete error notification [CHAR LIMIT=48] -->
+    <plurals name="delete_error_notification_title">
+        <item quantity="one">Couldn\'t delete <xliff:g id="count" example="1">%1$d</xliff:g> file</item>
+        <item quantity="other">Couldn\'t delete <xliff:g id="count" example="2">%1$d</xliff:g> files</item>
+    </plurals>
     <!-- Second line for notifications saying that more information will be shown after touching [CHAR LIMIT=48] -->
     <string name="notification_touch_for_details">Touch to view details</string>
     <!-- Label of a dialog button for retrying a failed operation [CHAR LIMIT=24] -->
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Events.java b/packages/DocumentsUI/src/com/android/documentsui/Events.java
index 1b5b60de..10a78b9 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Events.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Events.java
@@ -111,17 +111,15 @@
 
     public static final class MotionInputEvent implements InputEvent {
         private final MotionEvent mEvent;
-        private final RecyclerView mView;
         private final int mPosition;
 
         public MotionInputEvent(MotionEvent event, RecyclerView view) {
             mEvent = event;
-            mView = view;
 
             // Consider determining position lazily as an optimization.
-            View child = mView.findChildViewUnder(mEvent.getX(), mEvent.getY());
-            mPosition = (child != null)
-                    ? mView.getChildAdapterPosition(child)
+            View child = view.findChildViewUnder(mEvent.getX(), mEvent.getY());
+            mPosition = (child!= null)
+                    ? view.getChildAdapterPosition(child)
                     : RecyclerView.NO_POSITION;
         }
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java b/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java
index 5a80c39..4543162 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java
@@ -72,18 +72,12 @@
 
         String trustedPkg = mResources.getString(R.string.trusted_quick_viewer_package);
 
-        Intent intent = new Intent(Intent.ACTION_QUICK_VIEW);
-        intent.setDataAndType(mDocument.derivedUri, mDocument.mimeType);
-        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-
-        if (TextUtils.isEmpty(trustedPkg)) {
-            if (hasRegisteredHandler(intent)) {
-                return intent;
-            }
-        } else {
+        if (!TextUtils.isEmpty(trustedPkg)) {
+            Intent intent = new Intent(Intent.ACTION_QUICK_VIEW);
+            intent.setDataAndType(mDocument.derivedUri, mDocument.mimeType);
+            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
             intent.setPackage(trustedPkg);
             if (hasRegisteredHandler(intent)) {
-                // We have a trusted handler. Load all of the docs into the intent.
                 Cursor cursor = mSiblings.getCursor();
                 for (int i = 0; i < cursor.getCount(); i++) {
                     onNextItem(i, cursor);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index 580e2d8..d220f40 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -84,6 +84,7 @@
 import com.android.documentsui.DocumentsActivity;
 import com.android.documentsui.DocumentsApplication;
 import com.android.documentsui.Events;
+import com.android.documentsui.Events.MotionInputEvent;
 import com.android.documentsui.Menus;
 import com.android.documentsui.MessageBar;
 import com.android.documentsui.MimePredicate;
@@ -124,11 +125,13 @@
 
     public static final int REQUEST_COPY_DESTINATION = 1;
 
-    private static final String TAG = "DirectoryFragment";
-
-    private static final int LOADER_ID = 42;
     static final boolean DEBUG_ENABLE_DND = true;
 
+    private static final String TAG = "DirectoryFragment";
+    private static final int LOADER_ID = 42;
+    private static final int DELETE_UNDO_TIMEOUT = 5000;
+    private static final int DELETE_JOB_DELAY = 5500;
+
     private static final String EXTRA_TYPE = "type";
     private static final String EXTRA_ROOT = "root";
     private static final String EXTRA_DOC = "doc";
@@ -138,7 +141,7 @@
     private Model mModel;
     private MultiSelectManager mSelectionManager;
     private Model.UpdateListener mModelUpdateListener = new ModelUpdateListener();
-    private ItemClickListener mItemClickListener = new ItemClickListener();
+    private ItemEventListener mItemEventListener = new ItemEventListener();
 
     private IconHelper mIconHelper;
 
@@ -297,19 +300,7 @@
 
         mRecView.setAdapter(mAdapter);
 
-        GestureDetector.SimpleOnGestureListener listener =
-                new GestureDetector.SimpleOnGestureListener() {
-                    @Override
-                    public boolean onSingleTapUp(MotionEvent e) {
-                        return DirectoryFragment.this.onSingleTapUp(e);
-                    }
-                    @Override
-                    public boolean onDoubleTap(MotionEvent e) {
-                        Log.d(TAG, "Handling double tap.");
-                        return DirectoryFragment.this.onDoubleTap(e);
-                    }
-                };
-
+        GestureListener listener = new GestureListener();
         final GestureDetector detector = new GestureDetector(this.getContext(), listener);
         detector.setOnDoubleTapListener(listener);
 
@@ -339,7 +330,7 @@
                     : MultiSelectManager.MODE_SINGLE);
         mSelectionManager.addCallback(new SelectionModeListener());
 
-        mModel = new Model(context);
+        mModel = new Model();
         mModel.addUpdateListener(mAdapter);
         mModel.addUpdateListener(mModelUpdateListener);
 
@@ -466,22 +457,8 @@
                 operationType);
     }
 
-    private boolean onSingleTapUp(MotionEvent e) {
-        // Only respond to touch events.  Single-click mouse events are selection events and are
-        // handled by the selection manager.  Tap events that occur while the selection manager is
-        // active are also selection events.
-        if (Events.isTouchEvent(e) && !mSelectionManager.hasSelection()) {
-            String id = getModelId(e);
-            if (id != null) {
-                return handleViewItem(id);
-            }
-        }
-        return false;
-    }
-
     protected boolean onDoubleTap(MotionEvent e) {
         if (Events.isMouseEvent(e)) {
-            Log.d(TAG, "Handling double tap from mouse.");
             String id = getModelId(e);
             if (id != null) {
                 return handleViewItem(id);
@@ -852,16 +829,32 @@
     }
 
     private void deleteDocuments(final Selection selected) {
-        Context context = getActivity();
-        String message = Shared.getQuantityString(context, R.plurals.deleting, selected.size());
 
-        // Hide the files in the UI.
-        final SparseArray<String> toDelete = mAdapter.hide(selected.getAll());
+            checkArgument(!selected.isEmpty());
+            new GetDocumentsTask() {
+                @Override
+                void onDocumentsReady(List<DocumentInfo> docs) {
+                    // Hide the files in the UI.
+                    final SparseArray<String> hidden = mAdapter.hide(selected.getAll());
+
+                    checkState(DELETE_JOB_DELAY > DELETE_UNDO_TIMEOUT);
+                    String operationId = FileOperations.delete(
+                            getActivity(), docs, getDisplayState().stack,
+                            DELETE_JOB_DELAY);
+                    showDeleteSnackbar(hidden, operationId);
+                }
+            }.execute(selected);
+    }
+
+    private void showDeleteSnackbar(final SparseArray<String> hidden, final String jobId) {
+
+        Context context = getActivity();
+        String message = Shared.getQuantityString(context, R.plurals.deleting, hidden.size());
 
         // Show a snackbar informing the user that files will be deleted, and give them an option to
         // cancel.
         final Activity activity = getActivity();
-        Snackbars.makeSnackbar(activity, message, Snackbar.LENGTH_LONG)
+        Snackbars.makeSnackbar(activity, message, DELETE_UNDO_TIMEOUT)
                 .setAction(
                         R.string.undo,
                         new View.OnClickListener() {
@@ -874,22 +867,8 @@
                             public void onDismissed(Snackbar snackbar, int event) {
                                 if (event == Snackbar.Callback.DISMISS_EVENT_ACTION) {
                                     // If the delete was cancelled, just unhide the files.
-                                    mAdapter.unhide(toDelete);
-                                } else {
-                                    // Actually kick off the delete.
-                                    mModel.delete(
-                                            selected,
-                                            new Model.DeletionListener() {
-                                                @Override
-                                                  public void onError() {
-                                                      Snackbars.makeSnackbar(
-                                                              activity,
-                                                              R.string.toast_failed_delete,
-                                                              Snackbar.LENGTH_LONG)
-                                                              .show();
-
-                                                  }
-                                            });
+                                    FileOperations.cancel(activity, jobId);
+                                    mAdapter.unhide(hidden);
                                 }
                             }
                         })
@@ -926,7 +905,7 @@
 
     @Override
     public void initDocumentHolder(DocumentHolder holder) {
-        holder.addClickListener(mItemClickListener);
+        holder.addEventListener(mItemEventListener);
         holder.addOnKeyListener(mSelectionManager);
     }
 
@@ -1330,15 +1309,18 @@
         return mSelectionManager.getSelection().contains(modelId);
     }
 
-    private class ItemClickListener implements DocumentHolder.ClickListener {
+    private class ItemEventListener implements DocumentHolder.EventListener {
         @Override
-        public void onClick(DocumentHolder doc) {
-            if (mSelectionManager.hasSelection()) {
-                mSelectionManager.toggleSelection(doc.modelId);
-                mSelectionManager.setSelectionRangeBegin(doc.getAdapterPosition());
-            } else {
-                handleViewItem(doc.modelId);
-            }
+        public boolean onActivate(DocumentHolder doc) {
+            handleViewItem(doc.modelId);
+            return true;
+        }
+
+        @Override
+        public boolean onSelect(DocumentHolder doc) {
+            mSelectionManager.toggleSelection(doc.modelId);
+            mSelectionManager.setSelectionRangeBegin(doc.getAdapterPosition());
+            return true;
         }
     }
 
@@ -1366,4 +1348,54 @@
             showErrorView();
         }
     }
+
+    /**
+     * The gesture listener for items in the list/grid view. Interprets gestures and sends the
+     * events to the target DocumentHolder, whence they are routed to the appropriate listener.
+     */
+    private class GestureListener extends GestureDetector.SimpleOnGestureListener {
+        @Override
+        public boolean onSingleTapUp(MotionEvent e) {
+            // Single tap logic:
+            // If the selection manager is active, it gets first whack at handling tap
+            // events. Otherwise, tap events are routed to the target DocumentHolder.
+            boolean handled = mSelectionManager.onSingleTapUp(
+                        new MotionInputEvent(e, mRecView));
+
+            if (handled) {
+                return handled;
+            }
+
+            // Give the DocumentHolder a crack at the event.
+            DocumentHolder holder = getTarget(e);
+            if (holder != null) {
+                handled = holder.onSingleTapUp(e);
+            }
+
+            return handled;
+        }
+
+        @Override
+        public void onLongPress(MotionEvent e) {
+            // Long-press events get routed directly to the selection manager. They can be
+            // changed to route through the DocumentHolder if necessary.
+            mSelectionManager.onLongPress(new MotionInputEvent(e, mRecView));
+        }
+
+        @Override
+        public boolean onDoubleTap(MotionEvent e) {
+            // Double-tap events are handled directly by the DirectoryFragment. They can be changed
+            // to route through the DocumentHolder if necessary.
+            return DirectoryFragment.this.onDoubleTap(e);
+        }
+
+        private @Nullable DocumentHolder getTarget(MotionEvent e) {
+            View childView = mRecView.findChildViewUnder(e.getX(), e.getY());
+            if (childView != null) {
+                return (DocumentHolder) mRecView.getChildViewHolder(childView);
+            } else {
+                return null;
+            }
+        }
+    }
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentHolder.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentHolder.java
index 9ac9057..8acf1af 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentHolder.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentHolder.java
@@ -16,17 +16,21 @@
 
 package com.android.documentsui.dirlist;
 
+import static com.android.internal.util.Preconditions.checkNotNull;
 import static com.android.internal.util.Preconditions.checkState;
 
 import android.content.Context;
 import android.database.Cursor;
+import android.graphics.Rect;
 import android.support.annotation.Nullable;
 import android.support.v7.widget.RecyclerView;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 
+import com.android.documentsui.Events;
 import com.android.documentsui.R;
 import com.android.documentsui.State;
 
@@ -41,8 +45,9 @@
     final boolean mAlwaysShowSummary;
     final Context mContext;
 
-    private ListDocumentHolder.ClickListener mClickListener;
+    DocumentHolder.EventListener mEventListener;
     private View.OnKeyListener mKeyListener;
+    private View mSelectionHotspot;
 
     public DocumentHolder(Context context, ViewGroup parent, int layout) {
         this(context, inflateLayout(context, parent, layout));
@@ -58,6 +63,8 @@
         mDefaultItemColor = context.getColor(R.color.item_doc_background);
         mSelectedItemColor = context.getColor(R.color.item_doc_background_selected);
         mAlwaysShowSummary = context.getResources().getBoolean(R.bool.always_show_summary);
+
+        mSelectionHotspot = itemView.findViewById(R.id.icon_check);
     }
 
     /**
@@ -75,23 +82,21 @@
 
     @Override
     public boolean onKey(View v, int keyCode, KeyEvent event) {
+        // Event listener should always be set.
+        checkNotNull(mEventListener);
         // Intercept enter key-up events, and treat them as clicks.  Forward other events.
-        if (event.getAction() == KeyEvent.ACTION_UP &&
-                keyCode == KeyEvent.KEYCODE_ENTER) {
-            if (mClickListener != null) {
-                mClickListener.onClick(this);
-            }
-            return true;
+        if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_ENTER) {
+            return mEventListener.onActivate(this);
         } else if (mKeyListener != null) {
             return mKeyListener.onKey(v, keyCode, event);
         }
         return false;
     }
 
-    public void addClickListener(ListDocumentHolder.ClickListener listener) {
+    public void addEventListener(DocumentHolder.EventListener listener) {
         // Just handle one for now; switch to a list if necessary.
-        checkState(mClickListener == null);
-        mClickListener = listener;
+        checkState(mEventListener == null);
+        mEventListener = listener;
     }
 
     public void addOnKeyListener(View.OnKeyListener listener) {
@@ -104,6 +109,33 @@
         setEnabledRecursive(itemView, enabled);
     }
 
+    public boolean onSingleTapUp(MotionEvent event) {
+        if (Events.isMouseEvent(event)) {
+            // Mouse clicks select.
+            // TODO:  && input.isPrimaryButtonPressed(), but it is returning false.
+            if (mEventListener != null) {
+                return mEventListener.onSelect(this);
+            }
+        } else if (Events.isTouchEvent(event)) {
+            // Touch events select if they occur in the selection hotspot, otherwise they activate.
+            if (mEventListener == null) {
+                return false;
+            }
+
+            // Do everything in global coordinates - it makes things simpler.
+            Rect rect = new Rect();
+            mSelectionHotspot.getGlobalVisibleRect(rect);
+
+            // If the tap occurred within the icon rect, consider it a selection.
+            if (rect.contains((int)event.getRawX(), (int)event.getRawY())) {
+                return mEventListener.onSelect(this);
+            } else {
+                return mEventListener.onActivate(this);
+            }
+        }
+        return false;
+    }
+
     static void setEnabledRecursive(View itemView, boolean enabled) {
         if (itemView == null) return;
         if (itemView.isEnabled() == enabled) return;
@@ -122,7 +154,20 @@
         return inflater.inflate(layout, parent, false);
     }
 
-    interface ClickListener {
-        public void onClick(DocumentHolder doc);
+    /**
+     * Implement this in order to be able to respond to events coming from DocumentHolders.
+     */
+    interface EventListener {
+        /**
+         * @param doc The target DocumentHolder
+         * @return Whether the event was handled.
+         */
+        public boolean onActivate(DocumentHolder doc);
+
+        /**
+         * @param doc The target DocumentHolder
+         * @return Whether the event was handled.
+         */
+        public boolean onSelect(DocumentHolder doc);
     }
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java
index cf21d15..075b3ea 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java
@@ -24,11 +24,7 @@
 import static com.android.documentsui.model.DocumentInfo.getCursorString;
 import static com.android.internal.util.Preconditions.checkNotNull;
 
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
-import android.content.Context;
 import android.database.Cursor;
-import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Looper;
 import android.provider.DocumentsContract;
@@ -39,7 +35,6 @@
 
 import com.android.documentsui.BaseActivity.SiblingProvider;
 import com.android.documentsui.DirectoryResult;
-import com.android.documentsui.DocumentsApplication;
 import com.android.documentsui.RootCursorWrapper;
 import com.android.documentsui.dirlist.MultiSelectManager.Selection;
 import com.android.documentsui.model.DocumentInfo;
@@ -56,7 +51,6 @@
 public class Model implements SiblingProvider {
     private static final String TAG = "Model";
 
-    private Context mContext;
     private boolean mIsLoading;
     private List<UpdateListener> mUpdateListeners = new ArrayList<>();
     @Nullable private Cursor mCursor;
@@ -73,10 +67,6 @@
     @Nullable String info;
     @Nullable String error;
 
-    Model(Context context) {
-        mContext = context;
-    }
-
     /**
      * Generates a Model ID for a cursor entry that refers to a document. The Model ID is a unique
      * string that can be used to identify the document referred to by the cursor.
@@ -406,91 +396,6 @@
         return mCursor;
     }
 
-    public void delete(Selection selected, DeletionListener listener) {
-        final ContentResolver resolver = mContext.getContentResolver();
-        new DeleteFilesTask(resolver, listener).execute(selected);
-    }
-
-    /**
-     * A Task which collects the DocumentInfo for documents that have been marked for deletion,
-     * and actually deletes them.
-     */
-    private class DeleteFilesTask extends AsyncTask<Selection, Void, Void> {
-        private ContentResolver mResolver;
-        private DeletionListener mListener;
-        private boolean mHadTrouble;
-
-        /**
-         * @param resolver A ContentResolver for performing the actual file deletions.
-         * @param errorCallback A Runnable that is executed in the event that one or more errors
-         *     occurred while copying files.  Execution will occur on the UI thread.
-         */
-        public DeleteFilesTask(ContentResolver resolver, DeletionListener listener) {
-            mResolver = resolver;
-            mListener = listener;
-        }
-
-        @Override
-        protected Void doInBackground(Selection... selected) {
-            List<DocumentInfo> toDelete = null;
-            try {
-                toDelete = getDocuments(selected[0]);
-            } catch (NullPointerException e) {
-                Log.w(TAG, "Failed to retrieve documents for delete.");
-                mHadTrouble = true;
-                return null;
-            }
-
-            for (DocumentInfo doc : toDelete) {
-                if (!doc.isDeleteSupported()) {
-                    Log.w(TAG, doc + " could not be deleted.  Skipping...");
-                    mHadTrouble = true;
-                    continue;
-                }
-
-                ContentProviderClient client = null;
-                try {
-                    if (DEBUG) Log.d(TAG, "Deleting: " + doc.displayName);
-                    client = DocumentsApplication.acquireUnstableProviderOrThrow(
-                        mResolver, doc.derivedUri.getAuthority());
-                    DocumentsContract.deleteDocument(client, doc.derivedUri);
-                } catch (Exception e) {
-                    Log.w(TAG, "Failed to delete " + doc, e);
-                    mHadTrouble = true;
-                } finally {
-                    ContentProviderClient.releaseQuietly(client);
-                }
-            }
-
-            return null;
-        }
-
-        @Override
-        protected void onPostExecute(Void _) {
-            if (mHadTrouble) {
-                // TODO show which files failed? b/23720103
-                mListener.onError();
-                if (DEBUG) Log.d(TAG, "Deletion task completed.  Some deletions failed.");
-            } else {
-                if (DEBUG) Log.d(TAG, "Deletion task completed successfully.");
-            }
-
-            mListener.onCompletion();
-        }
-    }
-
-    static class DeletionListener {
-        /**
-         * Called when deletion has completed (regardless of whether an error occurred).
-         */
-        void onCompletion() {}
-
-        /**
-         * Called at the end of a deletion operation that produced one or more errors.
-         */
-        void onError() {}
-    }
-
     void addUpdateListener(UpdateListener listener) {
         mUpdateListeners.add(listener);
     }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java
index d868fb4..9cbcf8c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java
@@ -32,7 +32,6 @@
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
-import android.view.GestureDetector;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
@@ -90,29 +89,10 @@
             mBandManager = new BandController();
         }
 
-        GestureDetector.SimpleOnGestureListener listener =
-                new GestureDetector.SimpleOnGestureListener() {
-                    @Override
-                    public boolean onSingleTapUp(MotionEvent e) {
-                        return MultiSelectManager.this.onSingleTapUp(
-                                new MotionInputEvent(e, recyclerView));
-                    }
-                    @Override
-                    public void onLongPress(MotionEvent e) {
-                        MultiSelectManager.this.onLongPress(
-                                new MotionInputEvent(e, recyclerView));
-                    }
-                };
-
-        final GestureDetector detector = new GestureDetector(recyclerView.getContext(), listener);
-        detector.setOnDoubleTapListener(listener);
-
         recyclerView.addOnItemTouchListener(
                 new RecyclerView.OnItemTouchListener() {
                     @Override
                     public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
-                        detector.onTouchEvent(e);
-
                         if (mBandManager != null) {
                             return mBandManager.handleEvent(new MotionInputEvent(e, recyclerView));
                         }
@@ -287,13 +267,7 @@
     boolean onSingleTapUp(InputEvent input) {
         if (DEBUG) Log.d(TAG, "Processing tap event.");
         if (!hasSelection()) {
-            // if this is a mouse click on an item, start selection mode.
-            // TODO:  && input.isPrimaryButtonPressed(), but it is returning false.
-            if (input.isOverItem() && input.isMouseEvent()) {
-                int position = input.getItemPosition();
-                toggleSelection(position);
-                setSelectionRangeBegin(position);
-            }
+            // No selection active - do nothing.
             return false;
         }
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java b/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java
index 8f89b4e..f3195a7 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java
@@ -17,7 +17,10 @@
 package com.android.documentsui.services;
 
 import static android.os.SystemClock.elapsedRealtime;
-import static com.android.documentsui.DocumentsApplication.acquireUnstableProviderOrThrow;
+import static android.provider.DocumentsContract.buildChildDocumentsUri;
+import static android.provider.DocumentsContract.buildDocumentUri;
+import static android.provider.DocumentsContract.getDocumentId;
+import static android.provider.DocumentsContract.isChildDocument;
 import static com.android.documentsui.Shared.DEBUG;
 import static com.android.documentsui.model.DocumentInfo.getCursorLong;
 import static com.android.documentsui.model.DocumentInfo.getCursorString;
@@ -44,6 +47,7 @@
 import com.android.documentsui.R;
 import com.android.documentsui.model.DocumentInfo;
 import com.android.documentsui.model.DocumentStack;
+import com.android.documentsui.services.FileOperationService.OpType;
 
 import libcore.io.IoUtils;
 
@@ -57,12 +61,7 @@
 class CopyJob extends Job {
     private static final String TAG = "CopyJob";
     private static final int PROGRESS_INTERVAL_MILLIS = 1000;
-    final List<DocumentInfo> mSrcFiles;
-
-    // Provider clients are acquired for the duration of each copy job. Note that there is an
-    // implicit assumption that all srcs come from the same authority.
-    ContentProviderClient srcClient;
-    ContentProviderClient dstClient;
+    final List<DocumentInfo> mSrcs;
 
     private long mStartTime = -1;
     private long mBatchSize;
@@ -80,26 +79,39 @@
      *
      * @param srcs List of files to be copied.
      */
-    CopyJob(Context serviceContext, Context appContext, Listener listener,
-            String id, DocumentStack destination, List<DocumentInfo> srcs) {
-        super(OPERATION_COPY, serviceContext, appContext, listener, id, destination);
+    CopyJob(Context service, Context appContext, Listener listener,
+            String id, DocumentStack stack, List<DocumentInfo> srcs) {
+        super(service, appContext, listener, OPERATION_COPY, id, stack);
 
         checkArgument(!srcs.isEmpty());
-        this.mSrcFiles = srcs;
+        this.mSrcs = srcs;
+    }
+
+    /**
+     * @see @link {@link Job} constructor for most param descriptions.
+     *
+     * @param srcs List of files to be copied.
+     */
+    CopyJob(Context service, Context appContext, Listener listener,
+            @OpType int opType, String id, DocumentStack destination, List<DocumentInfo> srcs) {
+        super(service, appContext, listener, opType, id, destination);
+
+        checkArgument(!srcs.isEmpty());
+        this.mSrcs = srcs;
     }
 
     @Override
     Builder createProgressBuilder() {
         return super.createProgressBuilder(
-                serviceContext.getString(R.string.copy_notification_title),
+                service.getString(R.string.copy_notification_title),
                 R.drawable.ic_menu_copy,
-                serviceContext.getString(android.R.string.cancel),
+                service.getString(android.R.string.cancel),
                 R.drawable.ic_cab_cancel);
     }
 
     @Override
     public Notification getSetupNotification() {
-        return getSetupNotification(serviceContext.getString(R.string.copy_preparing));
+        return getSetupNotification(service.getString(R.string.copy_preparing));
     }
 
     public boolean shouldUpdateProgress() {
@@ -113,7 +125,7 @@
         mProgressBuilder.setContentInfo(
                 NumberFormat.getPercentInstance().format(completed));
         if (mRemainingTime > 0) {
-            mProgressBuilder.setContentText(serviceContext.getString(msgId,
+            mProgressBuilder.setContentText(service.getString(msgId,
                     DateUtils.formatDuration(mRemainingTime)));
         } else {
             mProgressBuilder.setContentText(null);
@@ -164,38 +176,28 @@
     }
 
     @Override
-    void run(FileOperationService service) throws RemoteException {
+    void start() throws RemoteException {
         mStartTime = elapsedRealtime();
 
-        // Acquire content providers.
-        srcClient = acquireUnstableProviderOrThrow(
-                getContentResolver(),
-                mSrcFiles.get(0).authority);
-        dstClient = acquireUnstableProviderOrThrow(
-                getContentResolver(),
-                stack.peek().authority);
-
         // client
-        mBatchSize = calculateSize(srcClient, mSrcFiles);
+        mBatchSize = calculateSize(mSrcs);
 
         DocumentInfo srcInfo;
         DocumentInfo dstInfo;
-        for (int i = 0; i < mSrcFiles.size() && !isCanceled(); ++i) {
-            srcInfo = mSrcFiles.get(i);
+        for (int i = 0; i < mSrcs.size() && !isCanceled(); ++i) {
+            srcInfo = mSrcs.get(i);
             dstInfo = stack.peek();
 
             // Guard unsupported recursive operation.
             if (dstInfo.equals(srcInfo) || isDescendentOf(srcInfo, dstInfo)) {
-                if (DEBUG) Log.d(TAG, "Skipping recursive operation on directory "
-                        + dstInfo.derivedUri);
-                onFileFailed(srcInfo);
+                onFileFailed(srcInfo,
+                        "Skipping recursive operation on directory " + dstInfo.derivedUri + ".");
                 continue;
             }
 
             if (DEBUG) Log.d(TAG,
-                    "Performing op-type:" + type() + " of " + srcInfo.displayName
-                    + " (" + srcInfo.derivedUri + ")" + " to " + dstInfo.displayName
-                    + " (" + dstInfo.derivedUri + ")");
+                    "Copying " + srcInfo.displayName + " (" + srcInfo.derivedUri + ")"
+                    + " to " + dstInfo.displayName + " (" + dstInfo.derivedUri + ")");
 
             processDocument(srcInfo, dstInfo);
         }
@@ -217,67 +219,69 @@
     /**
      * Copies a the given document to the given location.
      *
-     * @param srcInfo DocumentInfos for the documents to copy.
+     * @param src DocumentInfos for the documents to copy.
      * @param dstDirInfo The destination directory.
-     * @param mode The transfer mode (copy or move).
      * @return True on success, false on failure.
      * @throws RemoteException
      */
-    boolean processDocument(DocumentInfo srcInfo, DocumentInfo dstDirInfo) throws RemoteException {
+    boolean processDocument(DocumentInfo src, DocumentInfo dstDirInfo) throws RemoteException {
 
         // TODO: When optimized copy kicks in, we'll not making any progress updates.
         // For now. Local storage isn't using optimized copy.
 
-        // When copying within the same provider, try to use optimized copying and moving.
+        // When copying within the same provider, try to use optimized copying.
         // If not supported, then fallback to byte-by-byte copy/move.
-        if (srcInfo.authority.equals(dstDirInfo.authority)) {
-            if ((srcInfo.flags & Document.FLAG_SUPPORTS_COPY) != 0) {
-                if (DocumentsContract.copyDocument(srcClient, srcInfo.derivedUri,
+        if (src.authority.equals(dstDirInfo.authority)) {
+            if ((src.flags & Document.FLAG_SUPPORTS_COPY) != 0) {
+                if (DocumentsContract.copyDocument(getClient(src), src.derivedUri,
                         dstDirInfo.derivedUri) == null) {
-                    onFileFailed(srcInfo);
+                    onFileFailed(src,
+                            "Provider side copy failed for documents: " + src.derivedUri + ".");
+                    return false;
                 }
-                return false;
+                return true;
             }
         }
 
         // If we couldn't do an optimized copy...we fall back to vanilla byte copy.
-        return byteCopyDocument(srcInfo, dstDirInfo);
+        return byteCopyDocument(src, dstDirInfo);
     }
 
-    boolean byteCopyDocument(DocumentInfo srcInfo, DocumentInfo dstDirInfo)
+    boolean byteCopyDocument(DocumentInfo src, DocumentInfo dest)
             throws RemoteException {
         final String dstMimeType;
         final String dstDisplayName;
 
+        if (DEBUG) Log.d(TAG, "Doing byte copy of document: " + src);
         // If the file is virtual, but can be converted to another format, then try to copy it
         // as such format. Also, append an extension for the target mime type (if known).
-        if (srcInfo.isVirtualDocument()) {
+        if (src.isVirtualDocument()) {
             final String[] streamTypes = getContentResolver().getStreamTypes(
-                    srcInfo.derivedUri, "*/*");
+                    src.derivedUri, "*/*");
             if (streamTypes != null && streamTypes.length > 0) {
                 dstMimeType = streamTypes[0];
                 final String extension = MimeTypeMap.getSingleton().
                         getExtensionFromMimeType(dstMimeType);
-                dstDisplayName = srcInfo.displayName +
-                        (extension != null ? "." + extension : srcInfo.displayName);
+                dstDisplayName = src.displayName +
+                        (extension != null ? "." + extension : src.displayName);
             } else {
-                // The virtual file is not available as any alternative streamable format.
-                // TODO: Log failures.
-                onFileFailed(srcInfo);
+                onFileFailed(src, "Cannot copy virtual file. No streamable formats available.");
                 return false;
             }
         } else {
-            dstMimeType = srcInfo.mimeType;
-            dstDisplayName = srcInfo.displayName;
+            dstMimeType = src.mimeType;
+            dstDisplayName = src.displayName;
         }
 
         // Create the target document (either a file or a directory), then copy recursively the
         // contents (bytes or children).
-        final Uri dstUri = DocumentsContract.createDocument(dstClient,
-                dstDirInfo.derivedUri, dstMimeType, dstDisplayName);
+        final Uri dstUri = DocumentsContract.createDocument(
+                getClient(dest), dest.derivedUri, dstMimeType, dstDisplayName);
         if (dstUri == null) {
             // If this is a directory, the entire subdir will not be copied over.
-            onFileFailed(srcInfo);
+            onFileFailed(src,
+                    "Couldn't create destination document " + dstDisplayName
+                    + " in directory " + dest.displayName + ".");
             return false;
         }
 
@@ -285,15 +289,16 @@
         try {
             dstInfo = DocumentInfo.fromUri(getContentResolver(), dstUri);
         } catch (FileNotFoundException e) {
-            onFileFailed(srcInfo);
+            onFileFailed(src,
+                    "Could not load DocumentInfo for newly created file: " + dstUri + ".");
             return false;
         }
 
         final boolean success;
-        if (Document.MIME_TYPE_DIR.equals(srcInfo.mimeType)) {
-            success = copyDirectoryHelper(srcInfo, dstInfo);
+        if (Document.MIME_TYPE_DIR.equals(src.mimeType)) {
+            success = copyDirectoryHelper(src, dstInfo);
         } else {
-            success = copyFileHelper(srcInfo, dstInfo, dstMimeType);
+            success = copyFileHelper(src, dstInfo, dstMimeType);
         }
 
         return success;
@@ -303,13 +308,13 @@
      * Handles recursion into a directory and copying its contents. Note that in linux terms, this
      * does the equivalent of "cp src/* dst", not "cp -r src dst".
      *
-     * @param srcDirInfo Info of the directory to copy from. The routine will copy the directory's
+     * @param srcDir Info of the directory to copy from. The routine will copy the directory's
      *            contents, not the directory itself.
-     * @param dstDirInfo Info of the directory to copy to. Must be created beforehand.
+     * @param destDir Info of the directory to copy to. Must be created beforehand.
      * @return True on success, false if some of the children failed to copy.
      * @throws RemoteException
      */
-    private boolean copyDirectoryHelper(DocumentInfo srcDirInfo, DocumentInfo dstDirInfo)
+    private boolean copyDirectoryHelper(DocumentInfo srcDir, DocumentInfo destDir)
             throws RemoteException {
         // Recurse into directories. Copy children into the new subdirectory.
         final String queryColumns[] = new String[] {
@@ -323,13 +328,11 @@
         boolean success = true;
         try {
             // Iterate over srcs in the directory; copy to the destination directory.
-            final Uri queryUri = DocumentsContract.buildChildDocumentsUri(srcDirInfo.authority,
-                    srcDirInfo.documentId);
-            cursor = srcClient.query(queryUri, queryColumns, null, null, null);
-            DocumentInfo srcInfo;
-            while (cursor.moveToNext()) {
-                srcInfo = DocumentInfo.fromCursor(cursor, srcDirInfo.authority);
-                success &= processDocument(srcInfo, dstDirInfo);
+            final Uri queryUri = buildChildDocumentsUri(srcDir.authority, srcDir.documentId);
+            cursor = getClient(srcDir).query(queryUri, queryColumns, null, null, null);
+            while (cursor.moveToNext() && !isCanceled()) {
+                DocumentInfo src = DocumentInfo.fromCursor(cursor, srcDir.authority);
+                success &= processDocument(src, destDir);
             }
         } finally {
             IoUtils.closeQuietly(cursor);
@@ -347,49 +350,49 @@
      * @return True on success, false on error.
      * @throws RemoteException
      */
-    private boolean copyFileHelper(DocumentInfo srcInfo, DocumentInfo dstInfo, String mimeType)
+    private boolean copyFileHelper(DocumentInfo src, DocumentInfo dest, String mimeType)
             throws RemoteException {
-        // Copy an individual file.
         CancellationSignal canceller = new CancellationSignal();
         ParcelFileDescriptor srcFile = null;
         ParcelFileDescriptor dstFile = null;
-        InputStream src = null;
-        OutputStream dst = null;
+        InputStream in = null;
+        OutputStream out = null;
 
         boolean success = true;
         try {
             // If the file is virtual, but can be converted to another format, then try to copy it
             // as such format.
-            if (srcInfo.isVirtualDocument()) {
+            if (src.isVirtualDocument()) {
                 final AssetFileDescriptor srcFileAsAsset =
-                        srcClient.openTypedAssetFileDescriptor(
-                                srcInfo.derivedUri, mimeType, null, canceller);
+                        getClient(src).openTypedAssetFileDescriptor(
+                                src.derivedUri, mimeType, null, canceller);
                 srcFile = srcFileAsAsset.getParcelFileDescriptor();
-                src = new AssetFileDescriptor.AutoCloseInputStream(srcFileAsAsset);
+                in = new AssetFileDescriptor.AutoCloseInputStream(srcFileAsAsset);
             } else {
-                srcFile = srcClient.openFile(srcInfo.derivedUri, "r", canceller);
-                src = new ParcelFileDescriptor.AutoCloseInputStream(srcFile);
+                srcFile = getClient(src).openFile(src.derivedUri, "r", canceller);
+                in = new ParcelFileDescriptor.AutoCloseInputStream(srcFile);
             }
 
-            dstFile = dstClient.openFile(dstInfo.derivedUri, "w", canceller);
-            dst = new ParcelFileDescriptor.AutoCloseOutputStream(dstFile);
+            dstFile = getClient(dest).openFile(dest.derivedUri, "w", canceller);
+            out = new ParcelFileDescriptor.AutoCloseOutputStream(dstFile);
 
-            byte[] buffer = new byte[8192];
+            byte[] buffer = new byte[32 * 1024];
             int len;
-            while ((len = src.read(buffer)) != -1) {
+            while ((len = in.read(buffer)) != -1) {
                 if (isCanceled()) {
                     if (DEBUG) Log.d(TAG, "Canceled copy mid-copy. Id:" + id);
                     success = false;
                     break;
                 }
-                dst.write(buffer, 0, len);
+                out.write(buffer, 0, len);
                 makeCopyProgress(len);
             }
 
             srcFile.checkError();
         } catch (IOException e) {
             success = false;
-            onFileFailed(srcInfo);
+            onFileFailed(src, "Exception thrown while copying from "
+                    + src.derivedUri + " to " + dest.derivedUri + ".");
 
             if (dstFile != null) {
                 try {
@@ -400,20 +403,20 @@
             }
         } finally {
             // This also ensures the file descriptors are closed.
-            IoUtils.closeQuietly(src);
-            IoUtils.closeQuietly(dst);
+            IoUtils.closeQuietly(in);
+            IoUtils.closeQuietly(out);
         }
 
         if (!success) {
-            // Clean up half-copied files.
+            if (DEBUG) Log.d(TAG, "Cleaning up failed operation leftovers.");
             canceller.cancel();
             try {
-                DocumentsContract.deleteDocument(dstClient, dstInfo.derivedUri);
+                DocumentsContract.deleteDocument(getClient(dest), dest.derivedUri);
             } catch (RemoteException e) {
                 // RemoteExceptions usually signal that the connection is dead, so there's no
                 // point attempting to continue. Propagate the exception up so the copy job is
                 // cancelled.
-                Log.w(TAG, "Failed to cleanup after copy error: " + srcInfo.derivedUri, e);
+                Log.w(TAG, "Failed to cleanup after copy error: " + src.derivedUri, e);
                 throw e;
             }
         }
@@ -429,14 +432,14 @@
      * @return Size in bytes.
      * @throws RemoteException
      */
-    private static long calculateSize(ContentProviderClient client, List<DocumentInfo> srcs)
+    private long calculateSize(List<DocumentInfo> srcs)
             throws RemoteException {
         long result = 0;
 
         for (DocumentInfo src : srcs) {
             if (src.isDirectory()) {
                 // Directories need to be recursed into.
-                result += calculateFileSizesRecursively(client, src.derivedUri);
+                result += calculateFileSizesRecursively(getClient(src), src.derivedUri);
             } else {
                 result += src.size;
             }
@@ -452,8 +455,7 @@
     private static long calculateFileSizesRecursively(
             ContentProviderClient client, Uri uri) throws RemoteException {
         final String authority = uri.getAuthority();
-        final Uri queryUri = DocumentsContract.buildChildDocumentsUri(authority,
-                DocumentsContract.getDocumentId(uri));
+        final Uri queryUri = buildChildDocumentsUri(authority, getDocumentId(uri));
         final String queryColumns[] = new String[] {
                 Document.COLUMN_DOCUMENT_ID,
                 Document.COLUMN_MIME_TYPE,
@@ -468,7 +470,7 @@
                 if (Document.MIME_TYPE_DIR.equals(
                         getCursorString(cursor, Document.COLUMN_MIME_TYPE))) {
                     // Recurse into directories.
-                    final Uri dirUri = DocumentsContract.buildDocumentUri(authority,
+                    final Uri dirUri = buildDocumentUri(authority,
                             getCursorString(cursor, Document.COLUMN_DOCUMENT_ID));
                     result += calculateFileSizesRecursively(client, dirUri);
                 } else {
@@ -484,22 +486,32 @@
         return result;
     }
 
-    @Override
-    void cleanup() {
-        ContentProviderClient.releaseQuietly(srcClient);
-        ContentProviderClient.releaseQuietly(dstClient);
-    }
-
     /**
      * Returns true if {@code doc} is a descendant of {@code parentDoc}.
      * @throws RemoteException
      */
-    boolean isDescendentOf(DocumentInfo doc, DocumentInfo parentDoc)
+    boolean isDescendentOf(DocumentInfo doc, DocumentInfo parent)
             throws RemoteException {
-        if (parentDoc.isDirectory() && doc.authority.equals(parentDoc.authority)) {
-            return DocumentsContract.isChildDocument(
-                    dstClient, doc.derivedUri, parentDoc.derivedUri);
+        if (parent.isDirectory() && doc.authority.equals(parent.authority)) {
+            return isChildDocument(getClient(doc), doc.derivedUri, parent.derivedUri);
         }
         return false;
     }
-}
\ No newline at end of file
+
+    private void onFileFailed(DocumentInfo file, String msg) {
+        Log.w(TAG, msg);
+        onFileFailed(file);
+    }
+
+    @Override
+    public String toString() {
+        return new StringBuilder()
+                .append("CopyJob")
+                .append("{")
+                .append("id=" + id)
+                .append("srcs=" + mSrcs)
+                .append(", destination=" + stack)
+                .append("}")
+                .toString();
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/DeleteJob.java b/packages/DocumentsUI/src/com/android/documentsui/services/DeleteJob.java
new file mode 100644
index 0000000..6a2a794
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/DeleteJob.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.services;
+
+import static com.android.documentsui.Shared.DEBUG;
+import static com.android.documentsui.services.FileOperationService.OPERATION_DELETE;
+
+import android.app.Notification;
+import android.app.Notification.Builder;
+import android.content.Context;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.documentsui.R;
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.DocumentStack;
+
+import java.util.List;
+
+final class DeleteJob extends Job {
+
+    private static final String TAG = "DeleteJob";
+    private List<DocumentInfo> mSrcs;
+
+    /**
+     * Moves files to a destination identified by {@code destination}.
+     * Performs most work by delegating to CopyJob, then deleting
+     * a file after it has been copied.
+     *
+     * @see @link {@link Job} constructor for most param descriptions.
+     *
+     * @param srcs List of files to delete
+     */
+    DeleteJob(Context service, Context appContext, Listener listener,
+            String id, DocumentStack stack, List<DocumentInfo> srcs) {
+        super(service, appContext, listener, OPERATION_DELETE, id, stack);
+        this.mSrcs = srcs;
+    }
+
+    @Override
+    Builder createProgressBuilder() {
+        return super.createProgressBuilder(
+                service.getString(R.string.move_notification_title),
+                R.drawable.ic_menu_copy,
+                service.getString(android.R.string.cancel),
+                R.drawable.ic_cab_cancel);
+    }
+
+    @Override
+    public Notification getSetupNotification() {
+        return getSetupNotification(service.getString(R.string.delete_preparing));
+    }
+
+    @Override
+    Notification getFailureNotification() {
+        return getFailureNotification(
+                R.plurals.delete_error_notification_title, R.drawable.ic_menu_delete);
+    }
+
+    @Override
+    void start() throws RemoteException {
+        for (DocumentInfo doc : mSrcs) {
+            if (DEBUG) Log.d(TAG, "Deleting document @ " + doc.derivedUri);
+            if (!deleteDocument(doc)) {
+                Log.w(TAG, "Failed to delete document @ " + doc.derivedUri);
+                onFileFailed(doc);
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        return new StringBuilder()
+                .append("DeleteJob")
+                .append("{")
+                .append("id=" + id)
+                .append("srcs=" + mSrcs)
+                .append(", location=" + stack)
+                .append("}")
+                .toString();
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java
index 6d87ecf..aca2d7a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java
@@ -16,16 +16,16 @@
 
 package com.android.documentsui.services;
 
-import static android.os.SystemClock.elapsedRealtime;
 import static com.android.documentsui.Shared.DEBUG;
 import static com.android.internal.util.Preconditions.checkArgument;
 import static com.android.internal.util.Preconditions.checkNotNull;
 import static com.android.internal.util.Preconditions.checkState;
 
 import android.annotation.IntDef;
-import android.app.IntentService;
 import android.app.NotificationManager;
+import android.app.Service;
 import android.content.Intent;
+import android.os.IBinder;
 import android.os.PowerManager;
 import android.support.annotation.Nullable;
 import android.support.annotation.VisibleForTesting;
@@ -34,18 +34,32 @@
 import com.android.documentsui.Shared;
 import com.android.documentsui.model.DocumentInfo;
 import com.android.documentsui.model.DocumentStack;
-
-import com.google.common.base.Objects;
+import com.android.documentsui.services.Job.Factory;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 
-public class FileOperationService extends IntentService implements Job.Listener {
+import javax.annotation.concurrent.GuardedBy;
+
+public class FileOperationService extends Service implements Job.Listener {
+
+    private static final int DEFAULT_DELAY = 0;
+    private static final int MAX_DELAY = 10 * 1000;  // ten seconds
+    private static final int POOL_SIZE = 2;  // "pool size", not *max* "pool size".
+    private static final int NOTIFICATION_ID_PROGRESS = 0;
+    private static final int NOTIFICATION_ID_FAILURE = 1;
+
     public static final String TAG = "FileOperationService";
 
     public static final String EXTRA_JOB_ID = "com.android.documentsui.JOB_ID";
+    public static final String EXTRA_DELAY = "com.android.documentsui.DELAY";
     public static final String EXTRA_OPERATION = "com.android.documentsui.OPERATION";
     public static final String EXTRA_CANCEL = "com.android.documentsui.CANCEL";
     public static final String EXTRA_SRC_LIST = "com.android.documentsui.SRC_LIST";
@@ -68,23 +82,31 @@
     // TODO: Move it to a shared file when more operations are implemented.
     public static final int FAILURE_COPY = 1;
 
-    private PowerManager mPowerManager;
+    // The executor and job factory are visible for testing and non-final
+    // so we'll have a way to inject test doubles from the test. It's
+    // a sub-optimal arrangement.
+    @VisibleForTesting ScheduledExecutorService executor;
+    @VisibleForTesting Factory jobFactory;
 
+    private PowerManager mPowerManager;
+    private PowerManager.WakeLock mWakeLock;  // the wake lock, if held.
     private NotificationManager mNotificationManager;
 
-    // TODO: Rework service to support multiple concurrent jobs.
-    private volatile Job mJob;
+    @GuardedBy("mRunning")
+    private Map<String, JobRecord> mRunning = new HashMap<>();
 
-    // For testing only.
-    @Nullable private TestOnlyListener mJobFinishedListener;
-
-    public FileOperationService() {
-        super("FileOperationService");
-    }
+    private int mLastServiceId;
 
     @Override
     public void onCreate() {
-        super.onCreate();
+        // Allow tests to pre-set these with test doubles.
+        if (executor == null) {
+            executor = new ScheduledThreadPoolExecutor(POOL_SIZE);
+        }
+
+        if (jobFactory == null) {
+            jobFactory = Job.Factory.instance;
+        }
 
         if (DEBUG) Log.d(TAG, "Created.");
         mPowerManager = getSystemService(PowerManager.class);
@@ -92,69 +114,67 @@
     }
 
     @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        if (DEBUG) Log.d(TAG, "onStartCommand: " + intent);
-        if (intent.hasExtra(EXTRA_CANCEL)) {
-            handleCancel(intent);
-            return START_REDELIVER_INTENT;
-        } else {
-            return super.onStartCommand(intent, flags, startId);
+    public void onDestroy() {
+        if (DEBUG) Log.d(TAG, "Shutting down executor.");
+        List<Runnable> unfinished = executor.shutdownNow();
+        if (!unfinished.isEmpty()) {
+            Log.w(TAG, "Shutting down, but executor reports running jobs: " + unfinished);
         }
+        executor = null;
+        if (DEBUG) Log.d(TAG, "Destroyed.");
     }
 
     @Override
-    protected void onHandleIntent(Intent intent) {
-        if (DEBUG) Log.d(TAG, "onHandleIntent: " + intent);
+    public int onStartCommand(Intent intent, int flags, int serviceId) {
+        // TODO: Ensure we're not being called with retry or redeliver.
+        // checkArgument(flags == 0);  // retry and redeliver are not supported.
 
         String jobId = intent.getStringExtra(EXTRA_JOB_ID);
         @OpType int operationType = intent.getIntExtra(EXTRA_OPERATION, OPERATION_UNKNOWN);
         checkArgument(jobId != null);
+
         if (intent.hasExtra(EXTRA_CANCEL)) {
             handleCancel(intent);
-            return;
+        } else {
+            checkArgument(operationType != OPERATION_UNKNOWN);
+            handleOperation(intent, serviceId, jobId, operationType);
         }
 
-        checkArgument(operationType != OPERATION_UNKNOWN);
+        return START_NOT_STICKY;
+    }
 
-        PowerManager.WakeLock wakeLock = mPowerManager.newWakeLock(
-                PowerManager.PARTIAL_WAKE_LOCK, TAG);
+    private void handleOperation(Intent intent, int serviceId, String jobId, int operationType) {
+        if (DEBUG) Log.d(TAG, "onStartCommand: " + jobId + " with serviceId " + serviceId);
 
-        ArrayList<DocumentInfo> srcs = intent.getParcelableArrayListExtra(EXTRA_SRC_LIST);
-        DocumentStack stack = intent.getParcelableExtra(Shared.EXTRA_STACK);
+        // Track the service supplied id so we can stop the service once we're out of work to do.
+        mLastServiceId = serviceId;
 
-        Job job = createJob(operationType, jobId, srcs, stack);
-
-        try {
-            wakeLock.acquire();
-
-            mNotificationManager.notify(job.id, 0, job.getSetupNotification());
-            job.run(this);
-
-        } catch (Exception e) {
-            // Catch-all to prevent any copy errors from wedging the app.
-            Log.e(TAG, "Exceptions occurred during copying", e);
-        } finally {
-            if (DEBUG) Log.d(TAG, "Cleaning up after copy");
-
-            job.cleanup();
-            wakeLock.release();
-
-            // Dismiss the ongoing copy notification when the copy is done.
-            mNotificationManager.cancel(job.id, 0);
-
-            if (job.failed()) {
-                Log.e(TAG, job.failedFiles.size() + " files failed to copy");
-                mNotificationManager.notify(job.id, 0, job.getFailureNotification());
+        Job job = null;
+        synchronized (mRunning) {
+            if (mWakeLock == null) {
+                mWakeLock = mPowerManager.newWakeLock(
+                        PowerManager.PARTIAL_WAKE_LOCK, TAG);
             }
 
-            // TEST ONLY CODE...<raised eyebrows>
-            if (mJobFinishedListener != null) {
-                mJobFinishedListener.onFinished(job.failedFiles);
+            List<DocumentInfo> srcs = intent.getParcelableArrayListExtra(EXTRA_SRC_LIST);
+            DocumentStack stack = intent.getParcelableExtra(Shared.EXTRA_STACK);
+
+            job = createJob(operationType, jobId, srcs, stack);
+
+            if (job == null) {
+                return;
             }
 
-            deleteJob(job);
-            if (DEBUG) Log.d(TAG, "Done cleaning up");
+            mWakeLock.acquire();
         }
+
+        checkState(job != null);
+        int delay = intent.getIntExtra(EXTRA_DELAY, DEFAULT_DELAY);
+        checkArgument(delay <= MAX_DELAY);
+        if (DEBUG) Log.d(
+                TAG, "Scheduling job " + job.id + " to run in " + delay + " milliseconds.");
+        ScheduledFuture<?> future = executor.schedule(job, delay, TimeUnit.MILLISECONDS);
+        mRunning.put(jobId, new JobRecord(job, future));
     }
 
     /**
@@ -166,80 +186,151 @@
         checkArgument(intent.hasExtra(EXTRA_CANCEL));
         String jobId = checkNotNull(intent.getStringExtra(EXTRA_JOB_ID));
 
-        // Do nothing if the cancelled ID doesn't match the current job ID. This prevents racey
-        // cancellation requests from affecting unrelated copy jobs.  However, if the current job ID
-        // is null, the service most likely crashed and was revived by the incoming cancel intent.
-        // In that case, always allow the cancellation to proceed.
-        if (mJob != null && Objects.equal(jobId, mJob.id)) {
-            mJob.cancel();
+        if (DEBUG) Log.d(TAG, "handleCancel: " + jobId);
+
+        synchronized (mRunning) {
+            // Do nothing if the cancelled ID doesn't match the current job ID. This prevents racey
+            // cancellation requests from affecting unrelated copy jobs.  However, if the current job ID
+            // is null, the service most likely crashed and was revived by the incoming cancel intent.
+            // In that case, always allow the cancellation to proceed.
+            JobRecord record = mRunning.get(jobId);
+            if (record != null) {
+                record.job.cancel();
+
+                // If the job hasn't been started, cancel it and explicitly clean up.
+                // If it *has* been started, we wait for it to recognize this, then
+                // allow it stop working in an orderly fashion.
+                if (record.future.getDelay(TimeUnit.MILLISECONDS) > 0) {
+                    record.future.cancel(false);
+                    onFinished(record.job);
+                }
+            }
         }
 
         // Dismiss the progress notification here rather than in the copy loop. This preserves
         // interactivity for the user in case the copy loop is stalled.
         // Try to cancel it even if we don't have a job id...in case there is some sad
         // orphan notification.
-        mNotificationManager.cancel(jobId, 0);
+        mNotificationManager.cancel(jobId, NOTIFICATION_ID_PROGRESS);
+
+        // TODO: Guarantee the job is being finalized
     }
 
-    public static String createJobId() {
-        return String.valueOf(elapsedRealtime());
-    }
+    /**
+     * Creates a new job. Returns null if a job with {@code id} already exists.
+     * @return
+     */
+    @GuardedBy("mRunning")
+    private @Nullable Job createJob(
+            @OpType int operationType, String id, List<DocumentInfo> srcs, DocumentStack stack) {
 
-    Job createJob(
-            @OpType int operationType, String id, ArrayList<DocumentInfo> srcs,
-            DocumentStack stack) {
+        if (mRunning.containsKey(id)) {
+            Log.w(TAG, "Duplicate job id: " + id
+                    + ". Ignoring job request for srcs: " + srcs + ", stack: " + stack + ".");
+            return null;
+        }
 
-        checkState(mJob == null);
-
+        Job job = null;
         switch (operationType) {
             case OPERATION_COPY:
-                mJob = new CopyJob(this, getApplicationContext(), this, id, stack, srcs);
+                job = jobFactory.createCopy(this, getApplicationContext(), this, id, stack, srcs);
                 break;
             case OPERATION_MOVE:
-                mJob = new MoveJob(this, getApplicationContext(), this, id, stack, srcs);
+                job = jobFactory.createMove(this, getApplicationContext(), this, id, stack, srcs);
                 break;
             case OPERATION_DELETE:
-                throw new UnsupportedOperationException();
+                job = jobFactory.createDelete(this, getApplicationContext(), this, id, stack, srcs);
+                break;
             default:
                 throw new UnsupportedOperationException();
         }
 
-        return checkNotNull(mJob);
+        return checkNotNull(job);
     }
 
-    void deleteJob(Job job) {
-        checkArgument(job == mJob);
-        mJob = null;
+    @GuardedBy("mRunning")
+    private void deleteJob(Job job) {
+        if (DEBUG) Log.d(TAG, "deleteJob: " + job.id);
+
+        JobRecord record = mRunning.remove(job.id);
+        checkArgument(record != null);
+        record.job.cleanup();
+
+        if (mRunning.isEmpty()) {
+            shutdown();
+        }
+    }
+
+    /**
+     * Most likely shuts down. Won't shut down if service has a pending
+     * message. Thread pool is deal with in onDestroy.
+     */
+    private void shutdown() {
+        if (DEBUG) Log.d(TAG, "Shutting down. Last serviceId was " + mLastServiceId);
+        mWakeLock.release();
+        mWakeLock = null;
+
+        // Turns out, for us, stopSelfResult always returns false in tests,
+        // so we can't guard executor shutdown. For this reason we move
+        // executor shutdown to #onDestroy.
+        boolean gonnaStop = stopSelfResult(mLastServiceId);
+        if (DEBUG) Log.d(TAG, "Stopping service: " + gonnaStop);
+        if (!gonnaStop) {
+            Log.w(TAG, "Service should be stopping, but reports otherwise.");
+        }
+    }
+
+    @VisibleForTesting
+    boolean holdsWakeLock() {
+        return mWakeLock != null && mWakeLock.isHeld();
+    }
+
+    @Override
+    public void onStart(Job job) {
+        if (DEBUG) Log.d(TAG, "onStart: " + job.id);
+        mNotificationManager.notify(job.id, NOTIFICATION_ID_PROGRESS, job.getSetupNotification());
+    }
+
+    @Override
+    public void onFinished(Job job) {
+        if (DEBUG) Log.d(TAG, "onFinished: " + job.id);
+
+        // Dismiss the ongoing copy notification when the copy is done.
+        mNotificationManager.cancel(job.id, NOTIFICATION_ID_PROGRESS);
+
+        synchronized (mRunning) {
+            deleteJob(job);
+        }
     }
 
     @Override
     public void onProgress(CopyJob job) {
-        if (DEBUG) Log.d(TAG, "On copy progress...");
-        mNotificationManager.notify(job.id, 0, job.getProgressNotification());
+        if (DEBUG) Log.d(TAG, "onProgress: " + job.id);
+        mNotificationManager.notify(
+                job.id, NOTIFICATION_ID_PROGRESS, job.getProgressNotification());
     }
 
     @Override
-    public void onProgress(MoveJob job) {
-        if (DEBUG) Log.d(TAG, "On move progress...");
-        mNotificationManager.notify(job.id, 0, job.getProgressNotification());
+    public void onFailed(Job job) {
+        if (DEBUG) Log.d(TAG, "onFailed: " + job.id);
+        checkArgument(job.failed());
+        Log.e(TAG, "Job failed on files: " + job.failedFiles.size() + ".");
+        mNotificationManager.notify(job.id, NOTIFICATION_ID_FAILURE, job.getFailureNotification());
+        onFinished(job);  // Failed jobs don't call finished, so we do.
     }
 
-    /**
-     * Sets a callback to be run when the next run job is finished.
-     * This is test ONLY instrumentation. The alternative is for us to add
-     * broadcast intents SOLELY for the purpose of testing.
-     * @param listener
-     */
-    @VisibleForTesting
-    void addFinishedListener(TestOnlyListener listener) {
-        this.mJobFinishedListener = listener;
+    private static final class JobRecord {
+        private final Job job;
+        private final ScheduledFuture<?> future;
+
+        public JobRecord(Job job, ScheduledFuture<?> future) {
+            this.job = job;
+            this.future = future;
+        }
     }
 
-    /**
-     * Only used for testing. Is that obvious enough?
-     */
-    @VisibleForTesting
-    interface TestOnlyListener {
-        void onFinished(List<DocumentInfo> failed);
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;  // Boilerplate. See super#onBind
     }
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperations.java b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperations.java
index 88bf03b..f59a32a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperations.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperations.java
@@ -16,11 +16,13 @@
 
 package com.android.documentsui.services;
 
+import static android.os.SystemClock.elapsedRealtime;
 import static com.android.documentsui.Shared.DEBUG;
 import static com.android.documentsui.Shared.EXTRA_STACK;
 import static com.android.documentsui.Shared.asArrayList;
 import static com.android.documentsui.Shared.getQuantityString;
 import static com.android.documentsui.services.FileOperationService.EXTRA_CANCEL;
+import static com.android.documentsui.services.FileOperationService.EXTRA_DELAY;
 import static com.android.documentsui.services.FileOperationService.EXTRA_JOB_ID;
 import static com.android.documentsui.services.FileOperationService.EXTRA_OPERATION;
 import static com.android.documentsui.services.FileOperationService.EXTRA_SRC_LIST;
@@ -29,6 +31,7 @@
 import static com.android.documentsui.services.FileOperationService.OPERATION_MOVE;
 
 import android.app.Activity;
+import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
 import android.os.Parcelable;
@@ -50,8 +53,14 @@
 
     private static final String TAG = "FileOperations";
 
+    private static final IdBuilder idBuilder = new IdBuilder();
+
     private FileOperations() {}
 
+    public static String createJobId() {
+        return idBuilder.getNext();
+    }
+
     /**
      * Tries to start the activity. Returns the job id.
      */
@@ -67,7 +76,7 @@
             case OPERATION_MOVE:
                 return FileOperations.move(activity, srcDocs, stack);
             case OPERATION_DELETE:
-                return FileOperations.delete(activity, srcDocs, stack);
+                throw new UnsupportedOperationException("Delete isn't currently supported.");
             default:
                 throw new UnsupportedOperationException("Unknown operation: " + operationType);
         }
@@ -78,7 +87,7 @@
      *
      * @param context Context for the intent.
      * @param jobId The id of the job to cancel.
-     *     Use {@link FileOperationService#createJobId} if you don't have one handy.
+     *     Use {@link #createJobId} if you don't have one handy.
      * @param srcDocs A list of src files to copy.
      * @param dstStack The copy destination stack.
      */
@@ -97,13 +106,13 @@
      *
      * @param context Context for the intent.
      * @param jobId A unique jobid for this job.
-     *     Use {@link FileOperationService#createJobId} if you don't have one handy.
+     *     Use {@link #createJobId} if you don't have one handy.
      * @param srcDocs A list of src files to copy.
      * @param destination The copy destination stack.
      */
     public static String copy(
             Activity activity, List<DocumentInfo> srcDocs, DocumentStack destination) {
-        String jobId = FileOperationService.createJobId();
+        String jobId = createJobId();
         if (DEBUG) Log.d(TAG, "Initiating 'copy' operation id: " + jobId);
 
         Intent intent = createBaseIntent(OPERATION_COPY, activity, jobId, srcDocs, destination);
@@ -120,13 +129,13 @@
      * Starts the service for a move operation.
      *
      * @param jobId A unique jobid for this job.
-     *     Use {@link FileOperationService#createJobId} if you don't have one handy.
+     *     Use {@link #createJobId} if you don't have one handy.
      * @param srcDocs A list of src files to copy.
      * @param destination The move destination stack.
      */
     public static String move(
             Activity activity, List<DocumentInfo> srcDocs, DocumentStack destination) {
-        String jobId = FileOperationService.createJobId();
+        String jobId = createJobId();
         if (DEBUG) Log.d(TAG, "Initiating 'move' operation id: " + jobId);
 
         Intent intent = createBaseIntent(OPERATION_MOVE, activity, jobId, srcDocs, destination);
@@ -143,16 +152,19 @@
      * Starts the service for a move operation.
      *
      * @param jobId A unique jobid for this job.
-     *     Use {@link FileOperationService#createJobId} if you don't have one handy.
+     *     Use {@link #createJobId} if you don't have one handy.
      * @param srcDocs A list of src files to copy.
+     * @param delay Number of milliseconds to wait before executing the job.
      * @return Id of the job.
      */
     public static String delete(
-            Activity activity, List<DocumentInfo> srcDocs, DocumentStack location) {
-        String jobId = FileOperationService.createJobId();
-        if (DEBUG) Log.d(TAG, "Initiating 'delete' operation id: " + jobId);
+            Activity activity, List<DocumentInfo> srcDocs, DocumentStack location, int delay) {
+        String jobId = createJobId();
+        if (DEBUG) Log.d(TAG, "Initiating 'delete' operation id " + jobId
+                + " delayed by " + delay + " milliseconds.");
 
         Intent intent = createBaseIntent(OPERATION_DELETE, activity, jobId, srcDocs, location);
+        intent.putExtra(EXTRA_DELAY, delay);
         activity.startService(intent);
 
         return jobId;
@@ -162,15 +174,15 @@
      * Starts the service for a move operation.
      *
      * @param jobId A unique jobid for this job.
-     *     Use {@link FileOperationService#createJobId} if you don't have one handy.
+     *     Use {@link #createJobId} if you don't have one handy.
      * @param srcDocs A list of src files to copy.
      * @return Id of the job.
      */
     public static Intent createBaseIntent(
-            @OpType int operationType, Activity activity, String jobId,
+            @OpType int operationType, Context context, String jobId,
             List<DocumentInfo> srcDocs, DocumentStack localeStack) {
 
-        Intent intent = new Intent(activity, FileOperationService.class);
+        Intent intent = new Intent(context, FileOperationService.class);
         intent.putExtra(EXTRA_JOB_ID, jobId);
         intent.putParcelableArrayListExtra(
                 EXTRA_SRC_LIST, asArrayList(srcDocs));
@@ -187,4 +199,24 @@
                 getQuantityString(activity, contentId, fileCount),
                 Snackbar.LENGTH_SHORT);
     }
+
+    private static final class IdBuilder {
+
+        // Remember last job time so we can guard against collisions.
+        private long mLastJobTime;
+
+        // If we detect a collision, use subId to make distinct.
+        private int mSubId;
+
+        public synchronized String getNext() {
+            long time = elapsedRealtime();
+            if (time == mLastJobTime) {
+                mSubId++;
+            } else {
+                mSubId = 0;
+            }
+            mLastJobTime = time;
+            return String.valueOf(mLastJobTime) + "-" + String.valueOf(mSubId);
+        }
+    }
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/Job.java b/packages/DocumentsUI/src/com/android/documentsui/services/Job.java
index 5c37a87..f351df9 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/Job.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/Job.java
@@ -16,20 +16,30 @@
 
 package com.android.documentsui.services;
 
+import static com.android.documentsui.DocumentsApplication.acquireUnstableProviderOrThrow;
+import static com.android.documentsui.services.FileOperationService.EXTRA_CANCEL;
+import static com.android.documentsui.services.FileOperationService.EXTRA_FAILURE;
+import static com.android.documentsui.services.FileOperationService.EXTRA_JOB_ID;
+import static com.android.documentsui.services.FileOperationService.EXTRA_OPERATION;
+import static com.android.documentsui.services.FileOperationService.EXTRA_SRC_LIST;
+import static com.android.documentsui.services.FileOperationService.FAILURE_COPY;
 import static com.android.documentsui.services.FileOperationService.OPERATION_UNKNOWN;
 import static com.android.internal.util.Preconditions.checkArgument;
+import static com.android.internal.util.Preconditions.checkNotNull;
 
 import android.annotation.DrawableRes;
 import android.annotation.PluralsRes;
 import android.app.Notification;
 import android.app.Notification.Builder;
 import android.app.PendingIntent;
+import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Parcelable;
 import android.os.RemoteException;
 import android.provider.DocumentsContract;
+import android.util.Log;
 
 import com.android.documentsui.FilesActivity;
 import com.android.documentsui.R;
@@ -39,29 +49,37 @@
 import com.android.documentsui.services.FileOperationService.OpType;
 
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
-abstract class Job {
+/**
+ * A mashup of work item and ui progress update factory. Used by {@link FileOperationService}
+ * to do work and show progress relating to this work.
+ */
+abstract class Job implements Runnable {
 
-    final Context serviceContext;
+    private static final String TAG = "Job";
+    final Context service;
     final Context appContext;
     final Listener listener;
 
-    final @OpType int mOpType;
+    final @OpType int operationType;
     final String id;
     final DocumentStack stack;
 
     final ArrayList<DocumentInfo> failedFiles = new ArrayList<>();
     final Notification.Builder mProgressBuilder;
 
+    private final Map<String, ContentProviderClient> mClients = new HashMap<>();
     private volatile boolean mCanceled;
 
     /**
      * A simple progressable job, much like an AsyncTask, but with support
      * for providing various related notification, progress and navigation information.
-     * @param opType
+     * @param operationType
      *
-     * @param serviceContext The context of the service in which this job is running.
-     *     This is usually just "this".
+     * @param service The service context in which this job is running.
      * @param appContext The context of the invoking application. This is usually
      *     just {@code getApplicationContext()}.
      * @param listener
@@ -70,14 +88,15 @@
      *     destination in the Files app where the user will be take when the
      *     navigation intent is invoked (presumably from notification).
      */
-    Job(@OpType int opType, Context serviceContext, Context appContext, Listener listener,
-            String id, DocumentStack stack) {
+    Job(Context service, Context appContext, Listener listener,
+            @OpType int operationType, String id, DocumentStack stack) {
 
-        checkArgument(opType != OPERATION_UNKNOWN);
-        this.serviceContext = serviceContext;
+        checkArgument(operationType != OPERATION_UNKNOWN);
+
+        this.service = service;
         this.appContext = appContext;
         this.listener = listener;
-        mOpType = opType;
+        this.operationType = operationType;
 
         this.id = id;
         this.stack = stack;
@@ -85,18 +104,53 @@
         mProgressBuilder = createProgressBuilder();
     }
 
-    abstract void run(FileOperationService service) throws RemoteException;
-    abstract void cleanup();
-
-    @OpType int type() {
-        return mOpType;
+    @Override
+    public final void run() {
+        listener.onStart(this);
+        try {
+            start();
+        } catch (Exception e) {
+            // In the case of an unmanaged failure, we still want
+            // to resolve business in an orderly fashion. That'll
+            // ensure the service is shut down and notifications
+            // shown/closed.
+            listener.onFailed(this);
+        } finally {
+            if (failed()) {
+                listener.onFailed(this);
+            } else {
+                listener.onFinished(this);
+            }
+        }
     }
 
+    abstract void start() throws RemoteException;
+
     abstract Notification getSetupNotification();
     // TODO: Progress notification for deletes.
     // abstract Notification getProgressNotification(long bytesCopied);
     abstract Notification getFailureNotification();
 
+    ContentProviderClient getClient(DocumentInfo doc) throws RemoteException {
+        ContentProviderClient client = mClients.get(doc.authority);
+        if (client == null) {
+            // Acquire content providers.
+            client = acquireUnstableProviderOrThrow(
+                    getContentResolver(),
+                    doc.authority);
+
+            mClients.put(doc.authority, client);
+        }
+
+        return checkNotNull(client);
+    }
+
+    final void cleanup() {
+        for (ContentProviderClient client : mClients.values()) {
+            ContentProviderClient.releaseQuietly(client);
+        }
+    }
+
     final void cancel() {
         mCanceled = true;
     }
@@ -106,7 +160,7 @@
     }
 
     final ContentResolver getContentResolver() {
-        return serviceContext.getContentResolver();
+        return service.getContentResolver();
     }
 
     void onFileFailed(DocumentInfo file) {
@@ -117,6 +171,17 @@
         return !failedFiles.isEmpty();
     }
 
+    final boolean deleteDocument(DocumentInfo doc) {
+        try {
+            DocumentsContract.deleteDocument(getClient(doc), doc.derivedUri);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to delete file: " + doc.derivedUri, e);
+            return false;
+        }
+
+        return true;  // victory dance!
+    }
+
     Notification getSetupNotification(String content) {
         mProgressBuilder.setProgress(0, 0, true);
         mProgressBuilder.setContentText(content);
@@ -125,15 +190,15 @@
 
     Notification getFailureNotification(@PluralsRes int titleId, @DrawableRes int icon) {
         final Intent navigateIntent = buildNavigateIntent();
-        navigateIntent.putExtra(FileOperationService.EXTRA_FAILURE, FileOperationService.FAILURE_COPY);
-        navigateIntent.putExtra(FileOperationService.EXTRA_OPERATION, mOpType);
+        navigateIntent.putExtra(EXTRA_FAILURE, FAILURE_COPY);
+        navigateIntent.putExtra(EXTRA_OPERATION, operationType);
 
-        navigateIntent.putParcelableArrayListExtra(FileOperationService.EXTRA_SRC_LIST, failedFiles);
+        navigateIntent.putParcelableArrayListExtra(EXTRA_SRC_LIST, failedFiles);
 
-        final Notification.Builder errorBuilder = new Notification.Builder(serviceContext)
-                .setContentTitle(serviceContext.getResources().getQuantityString(titleId,
+        final Notification.Builder errorBuilder = new Notification.Builder(service)
+                .setContentTitle(service.getResources().getQuantityString(titleId,
                         failedFiles.size(), failedFiles.size()))
-                .setContentText(serviceContext.getString(R.string.notification_touch_for_details))
+                .setContentText(service.getString(R.string.notification_touch_for_details))
                 .setContentIntent(PendingIntent.getActivity(appContext, 0, navigateIntent,
                         PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT))
                 .setCategory(Notification.CATEGORY_ERROR)
@@ -147,7 +212,7 @@
     final Builder createProgressBuilder(
             String title, @DrawableRes int icon,
             String actionTitle, @DrawableRes int actionIcon) {
-        Notification.Builder progressBuilder = new Notification.Builder(serviceContext)
+        Notification.Builder progressBuilder = new Notification.Builder(service)
                 .setContentTitle(title)
                 .setContentIntent(
                         PendingIntent.getActivity(appContext, 0, buildNavigateIntent(), 0))
@@ -161,7 +226,7 @@
                 actionIcon,
                 actionTitle,
                 PendingIntent.getService(
-                        serviceContext,
+                        service,
                         0,
                         cancelIntent,
                         PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT));
@@ -173,21 +238,59 @@
      * Creates an intent for navigating back to the destination directory.
      */
     Intent buildNavigateIntent() {
-        Intent intent = new Intent(serviceContext, FilesActivity.class);
+        Intent intent = new Intent(service, FilesActivity.class);
         intent.setAction(DocumentsContract.ACTION_BROWSE);
         intent.putExtra(Shared.EXTRA_STACK, (Parcelable) stack);
         return intent;
     }
 
     Intent createCancelIntent() {
-        final Intent cancelIntent = new Intent(serviceContext, FileOperationService.class);
-        cancelIntent.putExtra(FileOperationService.EXTRA_CANCEL, true);
-        cancelIntent.putExtra(FileOperationService.EXTRA_JOB_ID, id);
+        final Intent cancelIntent = new Intent(service, FileOperationService.class);
+        cancelIntent.putExtra(EXTRA_CANCEL, true);
+        cancelIntent.putExtra(EXTRA_JOB_ID, id);
         return cancelIntent;
     }
 
+    @Override
+    public String toString() {
+        return new StringBuilder()
+                .append("Job")
+                .append("{")
+                .append("id=" + id)
+                .append("}")
+                .toString();
+    }
+
+    /**
+     * Factory class that facilitates our testing FileOperationService.
+     */
+    static class Factory {
+
+        static final Factory instance = new Factory();
+
+        Job createCopy(Context service, Context appContext, Listener listener,
+                String id, DocumentStack stack, List<DocumentInfo> srcs) {
+            return new CopyJob(service, appContext, listener, id, stack, srcs);
+        }
+
+        Job createMove(Context service, Context appContext, Listener listener,
+                String id, DocumentStack stack, List<DocumentInfo> srcs) {
+            return new MoveJob(service, appContext, listener, id, stack, srcs);
+        }
+
+        Job createDelete(Context service, Context appContext, Listener listener,
+                String id, DocumentStack stack, List<DocumentInfo> srcs) {
+            return new DeleteJob(service, appContext, listener, id, stack, srcs);
+        }
+    }
+
+    /**
+     * Listener interface employed by the service that owns us as well as tests.
+     */
     interface Listener {
+        void onStart(Job job);
+        void onFailed(Job job);
+        void onFinished(Job job);
         void onProgress(CopyJob job);
-        void onProgress(MoveJob job);
     }
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java b/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java
index 4817f58..7f6b1e1 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java
@@ -16,13 +16,14 @@
 
 package com.android.documentsui.services;
 
+import static com.android.documentsui.services.FileOperationService.OPERATION_MOVE;
+
 import android.app.Notification;
 import android.app.Notification.Builder;
 import android.content.Context;
 import android.os.RemoteException;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
-import android.util.Log;
 
 import com.android.documentsui.R;
 import com.android.documentsui.model.DocumentInfo;
@@ -43,28 +44,23 @@
      *
      * @param srcs List of files to be moved.
      */
-    MoveJob(Context serviceContext, Context appContext, Listener listener,
+    MoveJob(Context service, Context appContext, Listener listener,
             String id, DocumentStack destination, List<DocumentInfo> srcs) {
-        super(serviceContext, appContext, listener, id, destination, srcs);
-    }
-
-    @Override
-    int type() {
-        return FileOperationService.OPERATION_MOVE;
+        super(service, appContext, listener, OPERATION_MOVE, id, destination, srcs);
     }
 
     @Override
     Builder createProgressBuilder() {
         return super.createProgressBuilder(
-                serviceContext.getString(R.string.move_notification_title),
+                service.getString(R.string.move_notification_title),
                 R.drawable.ic_menu_copy,
-                serviceContext.getString(android.R.string.cancel),
+                service.getString(android.R.string.cancel),
                 R.drawable.ic_cab_cancel);
     }
 
     @Override
     public Notification getSetupNotification() {
-        return getSetupNotification(serviceContext.getString(R.string.move_preparing));
+        return getSetupNotification(service.getString(R.string.move_preparing));
     }
 
     @Override
@@ -78,47 +74,39 @@
                 R.plurals.move_error_notification_title, R.drawable.ic_menu_copy);
     }
 
-    /**
-     * Copies a the given document to the given location.
-     *
-     * @param srcInfo DocumentInfos for the documents to copy.
-     * @param dstDirInfo The destination directory.
-     * @param mode The transfer mode (copy or move).
-     * @return True on success, false on failure.
-     * @throws RemoteException
-     */
     @Override
-    boolean processDocument(DocumentInfo srcInfo, DocumentInfo dstDirInfo) throws RemoteException {
+    boolean processDocument(DocumentInfo src, DocumentInfo dest) throws RemoteException {
 
-        // TODO: When optimized copy kicks in, we're not making any progress updates. FIX IT!
+        // TODO: When optimized move kicks in, we're not making any progress updates. FIX IT!
 
-        // When copying within the same provider, try to use optimized copying and moving.
+        // When moving within the same provider, try to use optimized moving.
         // If not supported, then fallback to byte-by-byte copy/move.
-        if (srcInfo.authority.equals(dstDirInfo.authority)) {
-            if ((srcInfo.flags & Document.FLAG_SUPPORTS_MOVE) != 0) {
-                if (DocumentsContract.moveDocument(srcClient, srcInfo.derivedUri,
-                        dstDirInfo.derivedUri) == null) {
-                    onFileFailed(srcInfo);
+        if (src.authority.equals(dest.authority)) {
+            if ((src.flags & Document.FLAG_SUPPORTS_MOVE) != 0) {
+                if (DocumentsContract.moveDocument(getClient(src), src.derivedUri,
+                        dest.derivedUri) == null) {
+                    onFileFailed(src);
+                    return false;
                 }
-                return false;
+                return true;
             }
         }
 
         // If we couldn't do an optimized copy...we fall back to vanilla byte copy.
-        boolean success = byteCopyDocument(srcInfo, dstDirInfo);
+        boolean copied = byteCopyDocument(src, dest);
 
-        if (success) {
-            // This is racey. We should make sure that we never delete a directory after
-            // it changed, so we don't remove a file which had not been copied earlier
-            // to the target location.
-            try {
-                DocumentsContract.deleteDocument(srcClient, srcInfo.derivedUri);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Failed to delete source after copy: " + srcInfo.derivedUri, e);
-                return false;
-            }
-        }
+        return copied && !isCanceled() && deleteDocument(src);
+    }
 
-        return success;
+    @Override
+    public String toString() {
+        return new StringBuilder()
+                .append("MoveJob")
+                .append("{")
+                .append("id=" + id)
+                .append("srcs=" + mSrcs)
+                .append(", destination=" + stack)
+                .append("}")
+                .toString();
     }
 }
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/DocumentsProviderHelper.java b/packages/DocumentsUI/tests/src/com/android/documentsui/DocumentsProviderHelper.java
index 7abc99c..3c40b67 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/DocumentsProviderHelper.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/DocumentsProviderHelper.java
@@ -16,47 +16,68 @@
 
 package com.android.documentsui;
 
+import static android.provider.DocumentsContract.buildChildDocumentsUri;
+import static android.provider.DocumentsContract.buildDocumentUri;
+import static android.provider.DocumentsContract.buildRootsUri;
 import static com.android.documentsui.model.DocumentInfo.getCursorString;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.fail;
 
 import android.content.ContentProviderClient;
 import android.database.Cursor;
 import android.net.Uri;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.os.ParcelFileDescriptor.AutoCloseInputStream;
+import android.os.ParcelFileDescriptor.AutoCloseOutputStream;
 import android.os.RemoteException;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
 import android.provider.DocumentsContract.Root;
+import android.support.annotation.Nullable;
+import android.test.MoreAsserts;
+import android.util.Log;
 
+import com.android.documentsui.model.DocumentInfo;
 import com.android.documentsui.model.RootInfo;
 
+import com.google.android.collect.Lists;
+
 import libcore.io.IoUtils;
+import libcore.io.Streams;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Provides support for creation of documents in a test settings.
  */
 public class DocumentsProviderHelper {
 
-    private final ContentProviderClient mClient;
     private final String mAuthority;
+    private final ContentProviderClient mClient;
 
     public DocumentsProviderHelper(String authority, ContentProviderClient client) {
-        mClient = client;
         mAuthority = authority;
+        mClient = client;
     }
 
-    public RootInfo getRoot(String id) throws RemoteException {
-        final Uri rootsUri = DocumentsContract.buildRootsUri(mAuthority);
+    public RootInfo getRoot(String documentId) throws RemoteException {
+        final Uri rootsUri = buildRootsUri(mAuthority);
 
         Cursor cursor = null;
         try {
             cursor = mClient.query(rootsUri, null, null, null, null);
             while (cursor.moveToNext()) {
-                if (id.equals(getCursorString(cursor, Root.COLUMN_ROOT_ID))) {
+                if (documentId.equals(getCursorString(cursor, Root.COLUMN_ROOT_ID))) {
                     return RootInfo.fromRootsCursor(mAuthority, cursor);
                 }
             }
-            throw new IllegalArgumentException("Can't find matching root for id=" + id);
+            throw new IllegalArgumentException("Can't find matching root for id=" + documentId);
         } catch (Exception e) {
-            throw new RuntimeException("Can't load root for id=" + id , e);
+            throw new RuntimeException("Can't load root for id=" + documentId , e);
         } finally {
             IoUtils.closeQuietly(cursor);
         }
@@ -67,22 +88,205 @@
             throw new IllegalArgumentException("Name and mimetype probably interposed.");
         }
         try {
-            return DocumentsContract.createDocument(mClient, parentUri, mimeType, name);
+            Uri uri = DocumentsContract.createDocument(mClient, parentUri, mimeType, name);
+            return uri;
         } catch (RemoteException e) {
             throw new RuntimeException("Couldn't create document: " + name + " with mimetype " + mimeType, e);
         }
     }
 
+    public Uri createDocument(String parentId, String mimeType, String name) {
+        Uri parentUri = buildDocumentUri(mAuthority, parentId);
+        return createDocument(parentUri, mimeType, name);
+    }
+
+    public Uri createDocument(RootInfo root, String mimeType, String name) {
+        return createDocument(root.documentId, mimeType, name);
+    }
+
     public Uri createFolder(Uri parentUri, String name) {
         return createDocument(parentUri, Document.MIME_TYPE_DIR, name);
     }
 
-    public Uri createDocument(RootInfo root, String mimeType, String name) {
-        Uri rootUri = DocumentsContract.buildDocumentUri(mAuthority, root.documentId);
-        return createDocument(rootUri, mimeType, name);
+    public Uri createFolder(String parentId, String name) {
+        Uri parentUri = buildDocumentUri(mAuthority, parentId);
+        return createDocument(parentUri, Document.MIME_TYPE_DIR, name);
     }
 
     public Uri createFolder(RootInfo root, String name) {
         return createDocument(root, Document.MIME_TYPE_DIR, name);
     }
+
+    public void writeDocument(Uri documentUri, byte[] contents)
+            throws RemoteException, IOException {
+        ParcelFileDescriptor file = mClient.openFile(documentUri, "w", null);
+        try (AutoCloseOutputStream out = new AutoCloseOutputStream(file)) {
+            out.write(contents, 0, contents.length);
+        }
+    }
+
+    public byte[] readDocument(Uri documentUri) throws RemoteException, IOException {
+        Log.d("DocumentsProviderHelper", "Trying to read file contents: " + documentUri);
+        ParcelFileDescriptor file = mClient.openFile(documentUri, "r", null);
+        byte[] buf = null;
+        try (AutoCloseInputStream in = new AutoCloseInputStream(file)) {
+            buf = Streams.readFully(in);
+        }
+        return buf;
+    }
+
+    public void assertChildCount(Uri parentUri, int expected) throws Exception {
+        List<DocumentInfo> children = listChildren(parentUri);
+        assertEquals("Incorrect file count after copy", expected, children.size());
+    }
+
+    public void assertChildCount(String parentId, int expected) throws Exception {
+        List<DocumentInfo> children = listChildren(parentId);
+        assertEquals("Incorrect file count after copy", expected, children.size());
+    }
+
+    public void assertChildCount(RootInfo root, int expected) throws Exception {
+        assertChildCount(root.documentId, expected);
+    }
+
+    public void assertHasFile(Uri parentUri, String name) throws Exception {
+        List<DocumentInfo> children = listChildren(parentUri);
+        for (DocumentInfo child : children) {
+            if (name.equals(child.displayName) && !child.isDirectory()) {
+                return;
+            }
+        }
+        fail("Could not find file named=" + name + " in children " + children);
+    }
+
+    public void assertHasFile(String parentId, String name) throws Exception {
+        Uri parentUri = buildDocumentUri(mAuthority, parentId);
+        assertHasFile(parentUri, name);
+    }
+
+    public void assertHasFile(RootInfo root, String name) throws Exception {
+        assertHasFile(root.documentId, name);
+    }
+
+    public void assertHasDirectory(Uri parentUri, String name) throws Exception {
+        List<DocumentInfo> children = listChildren(parentUri);
+        for (DocumentInfo child : children) {
+            if (name.equals(child.displayName) && child.isDirectory()) {
+                return;
+            }
+        }
+        fail("Could not find name=" + name + " in children " + children);
+    }
+
+    public void assertHasDirectory(String parentId, String name) throws Exception {
+        Uri parentUri = buildDocumentUri(mAuthority, parentId);
+        assertHasDirectory(parentUri, name);
+    }
+
+    public void assertHasDirectory(RootInfo root, String name) throws Exception {
+        assertHasDirectory(root.documentId, name);
+    }
+
+    public void assertDoesNotExist(Uri parentUri, String name) throws Exception {
+        List<DocumentInfo> children = listChildren(parentUri);
+        for (DocumentInfo child : children) {
+            if (name.equals(child.displayName)) {
+                fail("Found name=" + name + " in children " + children);
+            }
+        }
+    }
+
+    public void assertDoesNotExist(String parentId, String name) throws Exception {
+        Uri parentUri = buildDocumentUri(mAuthority, parentId);
+        assertDoesNotExist(parentUri, name);
+    }
+
+    public void assertDoesNotExist(RootInfo root, String name) throws Exception {
+        assertDoesNotExist(root.getUri(), name);
+    }
+
+    public @Nullable DocumentInfo findFile(String parentId, String name)
+            throws Exception {
+        List<DocumentInfo> children = listChildren(parentId);
+        for (DocumentInfo child : children) {
+            if (name.equals(child.displayName)) {
+                return child;
+            }
+        }
+        return null;
+    }
+
+    public DocumentInfo findDocument(String parentId, String name) throws Exception {
+        List<DocumentInfo> children = listChildren(parentId);
+        for (DocumentInfo child : children) {
+            if (name.equals(child.displayName)) {
+                return child;
+            }
+        }
+        return null;
+    }
+
+    public DocumentInfo findDocument(Uri parentUri, String name) throws Exception {
+        List<DocumentInfo> children = listChildren(parentUri);
+        for (DocumentInfo child : children) {
+            if (name.equals(child.displayName)) {
+                return child;
+            }
+        }
+        return null;
+    }
+
+    public List<DocumentInfo> listChildren(Uri parentUri) throws Exception {
+        String id = DocumentsContract.getDocumentId(parentUri);
+        return listChildren(id);
+    }
+
+    public List<DocumentInfo> listChildren(String documentId) throws Exception {
+        Uri uri = buildChildDocumentsUri(mAuthority, documentId);
+        List<DocumentInfo> children = new ArrayList<>();
+        try (Cursor cursor = mClient.query(uri, null, null, null, null, null)) {
+            while (cursor.moveToNext()) {
+                children.add(DocumentInfo.fromDirectoryCursor(cursor));
+            }
+        }
+        return children;
+    }
+
+    public void assertFileContents(Uri documentUri, byte[] expected) throws Exception {
+        // TODO: Fix this: java.lang.SecurityException:
+        // The authority of the uri content:/document/%2Fdata%2Fuser%2F0%2Fcom.android.documentsui.\
+        // tests%2Fcache%2FTEST_ROOT_1%2Ftest1.txt does not match the one of the contentProvider: \
+        // com.android.documentsui.stubprovider
+//        MoreAsserts.assertEquals(
+//                "Copied file contents differ",
+//                expected, readDocument(documentUri));
+    }
+
+    public void assertFileContents(String parentId, String fileName, byte[] expected)
+            throws Exception {
+        DocumentInfo file = findFile(parentId, fileName);
+        assertNotNull(file);
+        assertFileContents(file.derivedUri, expected);
+    }
+
+    /**
+     * A helper method for StubProvider only. Won't work with other providers.
+     * @throws RemoteException
+     */
+    public Uri createVirtualFile(
+            RootInfo root, String path, String mimeType, byte[] content, String... streamTypes)
+                    throws RemoteException {
+
+        Bundle args = new Bundle();
+        args.putString(StubProvider.EXTRA_ROOT, root.rootId);
+        args.putString(StubProvider.EXTRA_PATH, path);
+        args.putString(Document.COLUMN_MIME_TYPE, mimeType);
+        args.putStringArrayList(StubProvider.EXTRA_STREAM_TYPES, Lists.newArrayList(streamTypes));
+        args.putByteArray(StubProvider.EXTRA_CONTENT, content);
+
+        Bundle result = mClient.call("createVirtualFile", null, args);
+        String documentId = result.getString(Document.COLUMN_DOCUMENT_ID);
+
+        return DocumentsContract.buildDocumentUri(mAuthority, documentId);
+    }
 }
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java b/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java
index fb6445b..a47d350 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java
@@ -48,8 +48,10 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 public class StubProvider extends DocumentsProvider {
 
@@ -57,9 +59,15 @@
     public static final String ROOT_0_ID = "TEST_ROOT_0";
     public static final String ROOT_1_ID = "TEST_ROOT_1";
 
+    public static final String EXTRA_SIZE = "com.android.documentsui.stubprovider.SIZE";
+    public static final String EXTRA_ROOT = "com.android.documentsui.stubprovider.ROOT";
+    public static final String EXTRA_PATH = "com.android.documentsui.stubprovider.PATH";
+    public static final String EXTRA_STREAM_TYPES
+            = "com.android.documentsui.stubprovider.STREAM_TYPES";
+    public static final String EXTRA_CONTENT = "com.android.documentsui.stubprovider.CONTENT";
+
     private static final String TAG = "StubProvider";
-    private static final String EXTRA_SIZE = "com.android.documentsui.stubprovider.SIZE";
-    private static final String EXTRA_ROOT = "com.android.documentsui.stubprovider.ROOT";
+
     private static final String STORAGE_SIZE_KEY = "documentsui.stubprovider.size";
     private static int DEFAULT_ROOT_SIZE = 1024 * 1024 * 100;  // 100 MB.
 
@@ -78,7 +86,7 @@
 
     private String mAuthority = DEFAULT_AUTHORITY;
     private SharedPreferences mPrefs;
-    private String mSimulateReadErrors;
+    private Set<String> mSimulateReadErrorIds = new HashSet<>();
 
     @Override
     public void attachInfo(Context context, ProviderInfo info) {
@@ -97,6 +105,7 @@
         Log.d(TAG, "Resetting storage.");
         removeChildrenRecursively(getContext().getCacheDir());
         mStorage.clear();
+        mSimulateReadErrorIds.clear();
 
         mPrefs = getContext().getSharedPreferences(
                 "com.android.documentsui.stubprovider.preferences", Context.MODE_PRIVATE);
@@ -296,6 +305,7 @@
     @Override
     public ParcelFileDescriptor openDocument(String docId, String mode, CancellationSignal signal)
             throws FileNotFoundException {
+
         final StubDocument document = mStorage.get(docId);
         if (document == null || !document.file.isFile()) {
             throw new FileNotFoundException();
@@ -305,17 +315,12 @@
         }
 
         if ("r".equals(mode)) {
-            final ParcelFileDescriptor pfd = ParcelFileDescriptor.open(document.file,
-                        ParcelFileDescriptor.MODE_READ_ONLY);
-            if (docId.equals(mSimulateReadErrors)) {
-                return new ParcelFileDescriptor(pfd) {
-                    @Override
-                    public void checkError() throws IOException {
-                        throw new IOException("Test error");
-                    }
-                };
+            if (mSimulateReadErrorIds.contains(docId)) {
+                Log.d(TAG, "Simulated errs enabled. Open in the wrong mode.");
+                return ParcelFileDescriptor.open(
+                        document.file, ParcelFileDescriptor.MODE_WRITE_ONLY);
             }
-            return pfd;
+            return ParcelFileDescriptor.open(document.file, ParcelFileDescriptor.MODE_READ_ONLY);
         }
         if ("w".equals(mode)) {
             return startWrite(document);
@@ -326,7 +331,11 @@
 
     @VisibleForTesting
     public void simulateReadErrorsForFile(Uri uri) {
-        mSimulateReadErrors = DocumentsContract.getDocumentId(uri);
+        simulateReadErrorsForFile(DocumentsContract.getDocumentId(uri));
+    }
+
+    public void simulateReadErrorsForFile(String id) {
+        mSimulateReadErrorIds.add(id);
     }
 
     @Override
@@ -337,9 +346,9 @@
 
     @Override
     public AssetFileDescriptor openTypedDocument(
-            String documentId, String mimeTypeFilter, Bundle opts, CancellationSignal signal)
+            String docId, String mimeTypeFilter, Bundle opts, CancellationSignal signal)
             throws FileNotFoundException {
-        final StubDocument document = mStorage.get(documentId);
+        final StubDocument document = mStorage.get(docId);
         if (document == null || !document.file.isFile() || document.streamTypes == null) {
             throw new FileNotFoundException();
         }
@@ -349,7 +358,7 @@
             if (mimeType.equals(mimeTypeFilter)) {
                 ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
                             document.file, ParcelFileDescriptor.MODE_READ_ONLY);
-                if (documentId.equals(mSimulateReadErrors)) {
+                if (mSimulateReadErrorIds.contains(docId)) {
                     pfd = new ParcelFileDescriptor(pfd) {
                         @Override
                         public void checkError() throws IOException {
@@ -454,11 +463,36 @@
             case "configure":
                 configure(arg, extras);
                 return null;
+            case "createVirtualFile":
+                return createVirtualFileFromBundle(extras);
+            case "simulateReadErrorsForFile":
+                simulateReadErrorsForFile(arg);
+                return null;
             default:
                 return super.call(method, arg, extras);
         }
     }
 
+    private Bundle createVirtualFileFromBundle(Bundle extras) {
+        try {
+            Uri uri = createVirtualFile(
+                    extras.getString(EXTRA_ROOT),
+                    extras.getString(EXTRA_PATH),
+                    extras.getString(Document.COLUMN_MIME_TYPE),
+                    extras.getStringArrayList(EXTRA_STREAM_TYPES),
+                    extras.getByteArray(EXTRA_CONTENT));
+
+            String documentId = DocumentsContract.getDocumentId(uri);
+            Bundle result = new Bundle();
+            result.putString(Document.COLUMN_DOCUMENT_ID, documentId);
+            return result;
+        } catch (IOException e) {
+            Log.e(TAG, "Couldn't create virtual file.");
+        }
+
+        return null;
+    }
+
     private void configure(String arg, Bundle extras) {
         Log.d(TAG, "Configure " + arg);
         String rootName = extras.getString(EXTRA_ROOT, ROOT_0_ID);
@@ -530,6 +564,7 @@
     public Uri createVirtualFile(
             String rootId, String path, String mimeType, List<String> streamTypes, byte[] content)
             throws FileNotFoundException, IOException {
+
         final File file = createFile(rootId, path, mimeType, content);
         final StubDocument parent = mStorage.get(getDocumentIdForFile(file.getParentFile()));
         if (parent == null) {
@@ -559,7 +594,7 @@
 
     private File createFile(String rootId, String path, String mimeType, byte[] content)
             throws FileNotFoundException, IOException {
-        Log.d(TAG, "Creating test file " + rootId + ":" + path);
+        Log.d(TAG, "Creating test file " + rootId + " : " + path);
         StubDocument root = mRoots.get(rootId).document;
         if (root == null) {
             throw new FileNotFoundException("No roots with the ID " + rootId + " were found");
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/DocumentHolderTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/DocumentHolderTest.java
new file mode 100644
index 0000000..16efc6e
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/DocumentHolderTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.dirlist;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.graphics.Rect;
+import android.os.SystemClock;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.MotionEvent.PointerCoords;
+import android.view.MotionEvent.PointerProperties;
+
+import com.android.documentsui.R;
+import com.android.documentsui.State;
+
+@SmallTest
+public class DocumentHolderTest extends AndroidTestCase {
+
+    DocumentHolder mHolder;
+    TestListener mListener;
+
+    public void setUp() throws Exception {
+        Context context = getContext();
+        LayoutInflater inflater = LayoutInflater.from(context);
+        mHolder = new DocumentHolder(getContext(), inflater.inflate(R.layout.item_doc_list, null)) {
+            @Override
+            public void bind(Cursor cursor, String modelId, State state) {}
+        };
+
+        mListener = new TestListener();
+        mHolder.addEventListener(mListener);
+
+        mHolder.itemView.requestLayout();
+        mHolder.itemView.invalidate();
+    }
+
+    public void testClickActivates() {
+        click();
+        mListener.assertSelected();
+    }
+
+    public void testTapActivates() {
+        tap();
+        mListener.assertActivated();
+    }
+
+    public void click() {
+        mHolder.onSingleTapUp(createEvent(MotionEvent.TOOL_TYPE_MOUSE));
+    }
+
+    public void tap() {
+        mHolder.onSingleTapUp(createEvent(MotionEvent.TOOL_TYPE_FINGER));
+    }
+
+    public MotionEvent createEvent(int tooltype) {
+        long time = SystemClock.uptimeMillis();
+
+        PointerProperties properties[] = new PointerProperties[] {
+                new PointerProperties()
+        };
+        properties[0].toolType = tooltype;
+
+        PointerCoords coords[] = new PointerCoords[] {
+                new PointerCoords()
+        };
+
+        Rect rect = new Rect();
+        mHolder.itemView.getHitRect(rect);
+        coords[0].x = rect.left;
+        coords[0].y = rect.top;
+
+        return MotionEvent.obtain(
+                time, // down time
+                time, // event time
+                MotionEvent.ACTION_UP, // action
+                1, // pointer count
+                properties, // pointer properties
+                coords, // pointer coords
+                0, // metastate
+                0, // button state
+                0, // xprecision
+                0, // yprecision
+                0, // deviceid
+                0, // edgeflags
+                0, // source
+                0 // flags
+                );
+    }
+
+    private class TestListener implements DocumentHolder.EventListener {
+        private boolean mActivated = false;
+        private boolean mSelected = false;
+
+        public void assertActivated() {
+            assertTrue(mActivated);
+            assertFalse(mSelected);
+        }
+
+        public void assertSelected() {
+            assertTrue(mSelected);
+            assertFalse(mActivated);
+        }
+
+        @Override
+        public boolean onActivate(DocumentHolder doc) {
+            mActivated = true;
+            return true;
+        }
+
+        @Override
+        public boolean onSelect(DocumentHolder doc) {
+            mSelected = true;
+            return true;
+        }
+
+    }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java
index 5ce1823..2244be9 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java
@@ -51,7 +51,7 @@
     public void setUp() {
 
         final Context testContext = TestContext.createStorageTestContext(getContext(), AUTHORITY);
-        mModel = new TestModel(testContext, AUTHORITY);
+        mModel = new TestModel(AUTHORITY);
         mModel.update(NAMES);
 
         DocumentsAdapter.Environment env = new TestEnvironment(testContext);
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelTest.java
index a5f0656..83299f0 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelTest.java
@@ -38,7 +38,6 @@
 import java.util.List;
 import java.util.Random;
 import java.util.Set;
-import java.util.concurrent.CountDownLatch;
 
 @SmallTest
 public class ModelTest extends AndroidTestCase {
@@ -96,7 +95,7 @@
         r.cursor = cursor;
 
         // Instantiate the model with a dummy view adapter and listener that (for now) do nothing.
-        model = new Model(context);
+        model = new Model();
         model.addUpdateListener(new DummyListener());
         model.update(r);
     }
@@ -303,16 +302,6 @@
         }
     }
 
-    // Tests that Model.delete works correctly.
-    public void testDelete() throws Exception {
-        // Simulate deleting 2 files.
-        List<DocumentInfo> docsBefore = getDocumentInfo(2, 3);
-        delete(2, 3);
-
-        provider.assertWasDeleted(docsBefore.get(0));
-        provider.assertWasDeleted(docsBefore.get(1));
-    }
-
     private void setupTestContext() {
         final MockContentResolver resolver = new MockContentResolver();
         context = new ContextWrapper(getContext()) {
@@ -335,29 +324,6 @@
         return s;
     }
 
-    private void delete(int... positions) throws InterruptedException {
-        Selection s = positionToSelection(positions);
-        final CountDownLatch latch = new CountDownLatch(1);
-
-        model.delete(
-                s,
-                new Model.DeletionListener() {
-                    @Override
-                    public void onError() {
-                        latch.countDown();
-                    }
-                    @Override
-                    void onCompletion() {
-                        latch.countDown();
-                    }
-                });
-        latch.await();
-    }
-
-    private List<DocumentInfo> getDocumentInfo(int... positions) {
-        return model.getDocuments(positionToSelection(positions));
-    }
-
     private static class DummyListener implements Model.UpdateListener {
         public void onModelUpdate(Model model) {}
         public void onModelUpdateFailed(Exception e) {}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManagerTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManagerTest.java
index 7a3b6d4..d3ef9aa 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManagerTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManagerTest.java
@@ -23,7 +23,6 @@
 
 import com.android.documentsui.TestInputEvent;
 import com.android.documentsui.dirlist.MultiSelectManager.Selection;
-
 import com.google.common.collect.Lists;
 
 import java.util.ArrayList;
@@ -55,13 +54,21 @@
         mManager.addCallback(mCallback);
     }
 
-    public void testMouseClick_StartsSelectionMode() {
-        click(7);
+    public void testSelection() {
+        // Check selection.
+        mManager.toggleSelection(items.get(7));
         assertSelection(items.get(7));
+        // Check deselection.
+        mManager.toggleSelection(items.get(7));
+        assertSelectionSize(0);
     }
 
-    public void testMouseClick_NotifiesSelectionChanged() {
-        click(7);
+    public void testSelection_NotifiesSelectionChanged() {
+        // Selection should notify.
+        mManager.toggleSelection(items.get(7));
+        mCallback.assertSelectionChanged();
+        // Deselection should notify.
+        mManager.toggleSelection(items.get(7));
         mCallback.assertSelectionChanged();
     }
 
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapperTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapperTest.java
index 398885c..7c324e7 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapperTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapperTest.java
@@ -23,15 +23,12 @@
 import android.support.v7.widget.RecyclerView;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
-import android.util.SparseArray;
 import android.view.ViewGroup;
 
 import com.android.documentsui.DirectoryResult;
 import com.android.documentsui.RootCursorWrapper;
 import com.android.documentsui.State;
 
-import java.util.List;
-
 @SmallTest
 public class SectionBreakDocumentsAdapterWrapperTest extends AndroidTestCase {
 
@@ -57,7 +54,7 @@
         final Context testContext = TestContext.createStorageTestContext(getContext(), AUTHORITY);
         DocumentsAdapter.Environment env = new TestEnvironment(testContext);
 
-        mModel = new TestModel(testContext, AUTHORITY);
+        mModel = new TestModel(AUTHORITY);
         mAdapter = new SectionBreakDocumentsAdapterWrapper(
             env,
             new ModelBackedDocumentsAdapter(
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestModel.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestModel.java
index f9cd3b2..d8c29db 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestModel.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestModel.java
@@ -16,16 +16,13 @@
 
 package com.android.documentsui.dirlist;
 
-import android.content.Context;
 import android.database.MatrixCursor;
 import android.provider.DocumentsContract.Document;
 
 import com.android.documentsui.DirectoryResult;
 import com.android.documentsui.RootCursorWrapper;
-import com.android.documentsui.dirlist.MultiSelectManager.Selection;
 
 import java.util.Random;
-import java.util.Set;
 
 public class TestModel extends Model {
 
@@ -39,14 +36,9 @@
     };
 
     private final String mAuthority;
-    private Set<String> mDeleted;
 
-    /**
-     * Creates a new context. context must be configured with provider for authority.
-     * @see TestContext#createStorageTestContext(Context, String).
-     */
-    public TestModel(Context context, String authority) {
-        super(context);
+    public TestModel(String authority) {
+        super();
         mAuthority = authority;
     }
 
@@ -75,12 +67,4 @@
     String idForPosition(int p) {
         return createModelId(mAuthority, Integer.toString(p));
     }
-
-    @Override
-    public void delete(Selection selected, DeletionListener listener) {
-        for (String id : selected.getAll()) {
-            mDeleted.add(id);
-        }
-        listener.onCompletion();
-    }
 }
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractCopyJobTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractCopyJobTest.java
new file mode 100644
index 0000000..ec21150
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractCopyJobTest.java
@@ -0,0 +1,157 @@
+/*
+ * 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.documentsui.services;
+
+import static com.google.common.collect.Lists.newArrayList;
+
+import android.net.Uri;
+import android.provider.DocumentsContract;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import com.android.documentsui.model.DocumentInfo;
+
+import java.util.List;
+
+@MediumTest
+public abstract class AbstractCopyJobTest<T extends CopyJob> extends AbstractJobTest<T> {
+
+    public void runCopyFilesTest() throws Exception {
+        Uri testFile1 = mDocs.createDocument(mSrcRoot, "text/plain", "test1.txt");
+        mDocs.writeDocument(testFile1, HAM_BYTES);
+
+        Uri testFile2 = mDocs.createDocument(mSrcRoot, "text/plain", "test2.txt");
+        mDocs.writeDocument(testFile2, FRUITY_BYTES);
+
+        createJob(newArrayList(testFile1, testFile2)).run();
+        mJobListener.waitForFinished();
+
+        mDocs.assertChildCount(mDestRoot, 2);
+        mDocs.assertHasFile(mDestRoot, "test1.txt");
+        mDocs.assertHasFile(mDestRoot, "test2.txt");
+        mDocs.assertFileContents(mDestRoot.documentId, "test1.txt", HAM_BYTES);
+        mDocs.assertFileContents(mDestRoot.documentId, "test2.txt", FRUITY_BYTES);
+    }
+
+    public void runCopyVirtualTypedFileTest() throws Exception {
+        Uri testFile = mDocs.createVirtualFile(
+                mSrcRoot, "/virtual.sth", "virtual/mime-type",
+                FRUITY_BYTES, "application/pdf", "text/html");
+
+        createJob(newArrayList(testFile)).run();
+
+        mJobListener.waitForFinished();
+
+        mDocs.assertChildCount(mDestRoot, 1);
+        mDocs.assertHasFile(mDestRoot, "virtual.sth.pdf");  // copy should convert file to PDF.
+        mDocs.assertFileContents(mDestRoot.documentId, "virtual.sth.pdf", FRUITY_BYTES);
+    }
+
+    public void runCopyVirtualNonTypedFileTest() throws Exception {
+        Uri testFile = mDocs.createVirtualFile(
+                mSrcRoot, "/virtual.sth", "virtual/mime-type",
+                FRUITY_BYTES);
+
+        createJob(newArrayList(testFile)).run();
+
+        mJobListener.waitForFinished();
+        mJobListener.assertFailed();
+        mJobListener.assertFilesFailed(newArrayList("virtual.sth"));
+
+        mDocs.assertChildCount(mDestRoot, 0);
+    }
+
+    public void runCopyEmptyDirTest() throws Exception {
+        Uri testDir = mDocs.createFolder(mSrcRoot, "emptyDir");
+
+        createJob(newArrayList(testDir)).run();
+        mJobListener.waitForFinished();
+
+        mDocs.assertChildCount(mDestRoot, 1);
+        mDocs.assertHasDirectory(mDestRoot, "emptyDir");
+    }
+
+    public void runCopyDirRecursivelyTest() throws Exception {
+
+        Uri testDir1 = mDocs.createFolder(mSrcRoot, "dir1");
+        mDocs.createDocument(testDir1, "text/plain", "test1.txt");
+
+        Uri testDir2 = mDocs.createFolder(testDir1, "dir2");
+        mDocs.createDocument(testDir2, "text/plain", "test2.txt");
+
+        createJob(newArrayList(testDir1)).run();
+        mJobListener.waitForFinished();
+
+        DocumentInfo dir1Copy = mDocs.findDocument(mDestRoot.documentId, "dir1");
+
+        mDocs.assertChildCount(dir1Copy.derivedUri, 2);
+        mDocs.assertHasDirectory(dir1Copy.derivedUri, "dir2");
+        mDocs.assertHasFile(dir1Copy.derivedUri, "test1.txt");
+
+        DocumentInfo dir2Copy = mDocs.findDocument(dir1Copy.documentId, "dir2");
+        mDocs.assertChildCount(dir2Copy.derivedUri, 1);
+        mDocs.assertHasFile(dir2Copy.derivedUri, "test2.txt");
+    }
+
+    public void runNoCopyDirToSelfTest() throws Exception {
+        Uri testDir = mDocs.createFolder(mSrcRoot, "someDir");
+
+        createJob(newArrayList(testDir), testDir).run();
+
+        mJobListener.waitForFinished();
+        mJobListener.assertFailed();
+        mJobListener.assertFilesFailed(newArrayList("someDir"));
+
+        mDocs.assertChildCount(mDestRoot, 0);
+    }
+
+    public void runNoCopyDirToDescendentTest() throws Exception {
+        Uri testDir = mDocs.createFolder(mSrcRoot, "someDir");
+        Uri destDir = mDocs.createFolder(testDir, "theDescendent");
+
+        createJob(newArrayList(testDir), destDir).run();
+
+        mJobListener.waitForFinished();
+        mJobListener.assertFailed();
+        mJobListener.assertFilesFailed(newArrayList("someDir"));
+
+        mDocs.assertChildCount(mDestRoot, 0);
+    }
+
+    public void runCopyFileWithReadErrorsTest() throws Exception {
+        Uri testFile = mDocs.createDocument(mSrcRoot, "text/plain", "test1.txt");
+        mDocs.writeDocument(testFile, HAM_BYTES);
+
+        String testId = DocumentsContract.getDocumentId(testFile);
+        mClient.call("simulateReadErrorsForFile", testId, null);
+
+        createJob(newArrayList(testFile)).run();
+
+        mJobListener.waitForFinished();
+        mJobListener.assertFailed();
+        mJobListener.assertFilesFailed(newArrayList("test1.txt"));
+
+        mDocs.assertChildCount(mDestRoot, 0);
+    }
+
+    /**
+     * Creates a job with a stack consisting to the default destination.
+     */
+    final T createJob(List<Uri> srcs) throws Exception {
+        Uri destination = DocumentsContract.buildDocumentUri(AUTHORITY, mDestRoot.documentId);
+        return createJob(srcs, destination);
+    }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractJobTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractJobTest.java
new file mode 100644
index 0000000..691af6a
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractJobTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.services;
+
+import static com.android.documentsui.StubProvider.ROOT_0_ID;
+import static com.android.documentsui.StubProvider.ROOT_1_ID;
+
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.net.Uri;
+import android.os.RemoteException;
+import android.provider.DocumentsContract;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import com.android.documentsui.DocumentsProviderHelper;
+import com.android.documentsui.StubProvider;
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.DocumentStack;
+import com.android.documentsui.model.RootInfo;
+
+import com.google.common.collect.Lists;
+
+import java.util.List;
+
+@MediumTest
+public abstract class AbstractJobTest<T extends Job> extends AndroidTestCase {
+
+    static String AUTHORITY = StubProvider.DEFAULT_AUTHORITY;
+    static final byte[] HAM_BYTES = "ham and cheese".getBytes();
+    static final byte[] FRUITY_BYTES = "I love fruit cakes!".getBytes();
+
+    Context mContext;
+    ContentResolver mResolver;
+    ContentProviderClient mClient;
+    DocumentsProviderHelper mDocs;
+    TestJobListener mJobListener;
+    RootInfo mSrcRoot;
+    RootInfo mDestRoot;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mJobListener = new TestJobListener();
+
+        // NOTE: Must be the "target" context, else security checks in content provider will fail.
+        mContext = getContext();
+        mResolver = mContext.getContentResolver();
+
+        mClient = mResolver.acquireContentProviderClient(AUTHORITY);
+        mDocs = new DocumentsProviderHelper(AUTHORITY, mClient);
+
+        initTestFiles();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        resetStorage();
+        mClient.release();
+        super.tearDown();
+    }
+
+    private void resetStorage() throws RemoteException {
+        mClient.call("clear", null, null);
+    }
+
+    private void initTestFiles() throws RemoteException {
+        mSrcRoot = mDocs.getRoot(ROOT_0_ID);
+        mDestRoot = mDocs.getRoot(ROOT_1_ID);
+    }
+
+    final T createJob(List<Uri> srcs, Uri destination) throws Exception {
+        DocumentStack stack = new DocumentStack();
+        stack.push(DocumentInfo.fromUri(mResolver, destination));
+
+        List<DocumentInfo> srcDocs = Lists.newArrayList();
+        for (Uri src : srcs) {
+            srcDocs.add(DocumentInfo.fromUri(mResolver, src));
+        }
+
+        return createJob(srcDocs, stack);
+    }
+
+    abstract T createJob(List<DocumentInfo> srcs, DocumentStack destination) throws Exception;
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/CopyJobTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/CopyJobTest.java
new file mode 100644
index 0000000..1acf2dc
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/CopyJobTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.documentsui.services;
+
+import android.test.suitebuilder.annotation.MediumTest;
+
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.DocumentStack;
+
+import java.util.List;
+
+@MediumTest
+public class CopyJobTest extends AbstractCopyJobTest<CopyJob> {
+
+    public void testCopyFiles() throws Exception {
+        runCopyFilesTest();
+    }
+
+    public void testCopyVirtualTypedFile() throws Exception {
+        runCopyVirtualTypedFileTest();
+    }
+
+    public void testCopyVirtualNonTypedFile() throws Exception {
+        runCopyVirtualNonTypedFileTest();
+    }
+
+    public void testCopyEmptyDir() throws Exception {
+        runCopyEmptyDirTest();
+    }
+
+    public void testCopyDirRecursively() throws Exception {
+        runCopyDirRecursivelyTest();
+    }
+
+    public void testNoCopyDirToSelf() throws Exception {
+        runNoCopyDirToSelfTest();
+    }
+
+    public void testNoCopyDirToDescendent() throws Exception {
+        runNoCopyDirToDescendentTest();
+    }
+
+    public void testCopyFileWithReadErrors() throws Exception {
+        runCopyFileWithReadErrorsTest();
+    }
+
+    @Override
+    CopyJob createJob(List<DocumentInfo> srcs, DocumentStack stack) throws Exception {
+        return new CopyJob(
+                mContext, mContext, mJobListener, FileOperations.createJobId(), stack, srcs);
+    }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/DeleteJobTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/DeleteJobTest.java
new file mode 100644
index 0000000..d6d10239
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/DeleteJobTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.services;
+
+import static com.google.common.collect.Lists.newArrayList;
+
+import android.net.Uri;
+import android.provider.DocumentsContract;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.DocumentStack;
+
+import java.util.List;
+
+@MediumTest
+public class DeleteJobTest extends AbstractJobTest<DeleteJob> {
+
+    public void testDeleteFiles() throws Exception {
+        Uri testFile1 = mDocs.createDocument(mSrcRoot, "text/plain", "test1.txt");
+        mDocs.writeDocument(testFile1, HAM_BYTES);
+
+        Uri testFile2 = mDocs.createDocument(mSrcRoot, "text/plain", "test2.txt");
+        mDocs.writeDocument(testFile2, FRUITY_BYTES);
+
+        createJob(newArrayList(testFile1, testFile2)).run();
+        mJobListener.waitForFinished();
+
+        mDocs.assertChildCount(mSrcRoot, 0);
+    }
+
+    /**
+     * Creates a job with a stack consisting to the default src directory.
+     */
+    private final DeleteJob createJob(List<Uri> srcs) throws Exception {
+        Uri stack = DocumentsContract.buildDocumentUri(AUTHORITY, mSrcRoot.documentId);
+        return createJob(srcs, stack);
+    }
+
+    @Override
+    DeleteJob createJob(List<DocumentInfo> srcs, DocumentStack stack) throws Exception {
+        return new DeleteJob(
+                mContext, mContext, mJobListener, FileOperations.createJobId(), stack, srcs);
+    }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/FileOperationServiceTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/FileOperationServiceTest.java
index 35aad60..4d5392e 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/services/FileOperationServiceTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/FileOperationServiceTest.java
@@ -16,588 +16,178 @@
 
 package com.android.documentsui.services;
 
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.Intent;
-import android.content.pm.ProviderInfo;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Parcelable;
-import android.os.RemoteException;
-import android.provider.DocumentsContract;
-import android.test.MoreAsserts;
-import android.test.ServiceTestCase;
-import android.test.mock.MockContentResolver;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.util.Log;
+import static com.android.documentsui.services.FileOperationService.OPERATION_COPY;
+import static com.android.documentsui.services.FileOperations.createBaseIntent;
+import static com.android.documentsui.services.FileOperations.createJobId;
+import static com.google.android.collect.Lists.newArrayList;
 
-import com.android.documentsui.DocumentsProviderHelper;
-import com.android.documentsui.Shared;
-import com.android.documentsui.StubProvider;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.test.ServiceTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+
 import com.android.documentsui.model.DocumentInfo;
 import com.android.documentsui.model.DocumentStack;
-import com.android.documentsui.model.RootInfo;
+import com.android.documentsui.services.Job.Listener;
 
-import com.google.common.collect.Lists;
-
-import libcore.io.IoUtils;
-import libcore.io.Streams;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
 
+/**
+ * TODO: Test progress updates.
+ */
 @MediumTest
 public class FileOperationServiceTest extends ServiceTestCase<FileOperationService> {
 
+    private static final DocumentInfo ALPHA_DOC = createDoc("alpha");
+    private static final DocumentInfo BETA_DOC = createDoc("alpha");
+    private static final DocumentInfo GAMMA_DOC = createDoc("gamma");
+    private static final DocumentInfo DELTA_DOC = createDoc("delta");
+
+    private FileOperationService mService;
+    private TestScheduledExecutorService mExecutor;
+    private TestJobFactory mJobFactory;
+
     public FileOperationServiceTest() {
         super(FileOperationService.class);
     }
 
-    private static String AUTHORITY = "com.android.documentsui.stubprovider";
-    private static String SRC_ROOT = StubProvider.ROOT_0_ID;
-    private static String DST_ROOT = StubProvider.ROOT_1_ID;
-    private static String TAG = "CopyTest";
-
-    private Context mContext;
-    private TestContentResolver mResolver;
-    private ContentProviderClient mClient;
-    private DocumentsProviderHelper mDocHelper;
-    private StubProvider mStorage;
-    private Context mSystemContext;
-    private CopyJobListener mListener;
-
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+        setupService();  // must be called first for our test setup to work correctly.
 
-        mListener = new CopyJobListener();
-        setupTestContext();
-        mClient = mResolver.acquireContentProviderClient(AUTHORITY);
+        mExecutor = new TestScheduledExecutorService();
+        mJobFactory = new TestJobFactory();
 
-        // Reset the stub provider's storage.
-        mStorage.clearCacheAndBuildRoots();
+        // Install test doubles.
+        mService = getService();
 
-        mDocHelper = new DocumentsProviderHelper(AUTHORITY, mClient);
+        assertNull(mService.executor);
+        mService.executor = mExecutor;
 
-        assertDestFileCount(0);
+        assertNull(mService.jobFactory);
+        mService.jobFactory = mJobFactory;
     }
 
-    @Override
-    protected void tearDown() throws Exception {
-        mClient.release();
-        super.tearDown();
+    public void testRunsJobs() throws Exception {
+        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
+        startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC));
+
+        mExecutor.runAll();
+        mJobFactory.assertAllJobsStarted();
     }
 
-    public void testCopyFile() throws Exception {
-        String srcPath = "/test0.txt";
-        Uri testFile = mStorage.createRegularFile(SRC_ROOT, srcPath, "text/plain",
-                "The five boxing wizards jump quickly".getBytes());
+    public void testRunsJobs_AfterFailure() throws Exception {
+        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
+        startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC));
 
-        startService(createCopyIntent(Lists.newArrayList(testFile)));
+        mJobFactory.jobs.get(0).fail(ALPHA_DOC);
 
-        // 2 operations: file creation, then writing data.
-        mResolver.waitForChanges(2);
-
-        // Verify that one file was copied; check file contents.
-        assertDestFileCount(1);
-        assertCopied(srcPath);
+        mExecutor.runAll();
+        mJobFactory.assertAllJobsStarted();
     }
 
-    public void testCopyVirtualTypedFile() throws Exception {
-        String srcPath = "/virtual.sth";
-        String expectedDstPath = "/virtual.sth.pdf";
-        ArrayList<String> streamTypes = new ArrayList<>();
-        streamTypes.add("application/pdf");
-        streamTypes.add("text/html");
-        String testContent = "I love fruit cakes!";
-        Uri testFile = mStorage.createVirtualFile(SRC_ROOT, srcPath, "virtual/mime-type",
-                streamTypes, testContent.getBytes());
+    public void testHoldsWakeLockWhileWorking() throws Exception {
+        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
 
-        startService(createCopyIntent(Lists.newArrayList(testFile)));
-
-        // 2 operations: file creation, then writing data.
-        mResolver.waitForChanges(2);
-
-        // Verify that one file was copied.
-        assertDestFileCount(1);
-
-        byte[] dstContent = readFile(DST_ROOT, expectedDstPath);
-        MoreAsserts.assertEquals("Moved file contents differ", testContent.getBytes(), dstContent);
+        assertTrue(mService.holdsWakeLock());
     }
 
-    public void testMoveFile() throws Exception {
-        String srcPath = "/test0.txt";
-        String testContent = "The five boxing wizards jump quickly";
-        Uri testFile = mStorage.createRegularFile(SRC_ROOT, srcPath, "text/plain",
-                testContent.getBytes());
+    public void testReleasesWakeLock_AfterSuccess() throws Exception {
+        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
 
-        Intent moveIntent = createCopyIntent(Lists.newArrayList(testFile));
-        moveIntent.putExtra(
-                FileOperationService.EXTRA_OPERATION,
-                FileOperationService.OPERATION_MOVE);
-        startService(moveIntent);
-
-        // 3 operations: file creation, writing data, deleting original.
-        mResolver.waitForChanges(3);
-
-        // Verify that one file was moved; check file contents.
-        assertDestFileCount(1);
-        assertDoesNotExist(SRC_ROOT, srcPath);
-
-        byte[] dstContent = readFile(DST_ROOT, srcPath);
-        MoreAsserts.assertEquals("Moved file contents differ", testContent.getBytes(), dstContent);
+        assertTrue(mService.holdsWakeLock());
+        mExecutor.runAll();
+        assertFalse(mService.holdsWakeLock());
     }
 
-    public void testCopyMultipleFiles() throws Exception {
-        String testContent[] = {
-                "The five boxing wizards jump quickly",
-                "The quick brown fox jumps over the lazy dog",
-                "Jackdaws love my big sphinx of quartz"
-        };
-        String srcPaths[] = {
-                "/test0.txt",
-                "/test1.txt",
-                "/test2.txt"
-        };
-        List<Uri> testFiles = Lists.newArrayList(
-                mStorage.createRegularFile(SRC_ROOT, srcPaths[0], "text/plain",
-                        testContent[0].getBytes()),
-                mStorage.createRegularFile(SRC_ROOT, srcPaths[1], "text/plain",
-                        testContent[1].getBytes()),
-                mStorage.createRegularFile(SRC_ROOT, srcPaths[2], "text/plain",
-                        testContent[2].getBytes()));
+    public void testReleasesWakeLock_AfterFailure() throws Exception {
+        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
 
-        // Copy all the test files.
-        startService(createCopyIntent(testFiles));
-
-        // 3 file creations, 3 file writes.
-        mResolver.waitForChanges(6);
-
-        assertDestFileCount(3);
-        for (String path : srcPaths) {
-            assertCopied(path);
-        }
+        assertTrue(mService.holdsWakeLock());
+        mExecutor.runAll();
+        assertFalse(mService.holdsWakeLock());
     }
 
-    public void testCopyEmptyDir() throws Exception {
-        String srcPath = "/emptyDir";
-        Uri testDir = createTestDirectory(srcPath);
+    public void testShutdownStopsExecutor_AfterSuccess() throws Exception {
+        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
 
-        startService(createCopyIntent(Lists.newArrayList(testDir)));
+        mExecutor.assertAlive();
 
-        // Just 1 operation: Directory creation.
-        mResolver.waitForChanges(1);
+        mExecutor.runAll();
+        shutdownService();
 
-        assertDestFileCount(1);
-
-        // Verify that the dst exists and is a directory.
-        File dst = mStorage.getFile(DST_ROOT, srcPath);
-        assertTrue(dst.isDirectory());
+        mExecutor.assertShutdown();
     }
 
-    public void testNoCopyDirToSelf() throws Exception {
-        Uri testDir = createTestDirectory("/someDir");
+    public void testShutdownStopsExecutor_AfterMixedFailures() throws Exception {
+        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
+        startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC));
 
-        Intent intent = createCopyIntent(Lists.newArrayList(testDir), testDir);
-        startService(intent);
+        mJobFactory.jobs.get(0).fail(ALPHA_DOC);
 
-        getService().addFinishedListener(mListener);
+        mExecutor.runAll();
+        shutdownService();
 
-        mListener.waitForFinished();
-        mListener.assertFailedCount(1);
-        mListener.assertFileFailed("someDir");
-
-        assertDestFileCount(0);
+        mExecutor.assertShutdown();
     }
 
-    public void testNoCopyDirToDescendent() throws Exception {
-        Uri testDir = createTestDirectory("/someDir");
-        Uri descDir = createTestDirectory("/someDir/theDescendent");
+    public void testShutdownStopsExecutor_AfterTotalFailure() throws Exception {
+        startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
+        startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC));
 
-        Intent intent = createCopyIntent(Lists.newArrayList(testDir), descDir);
-        startService(intent);
-        getService().addFinishedListener(mListener);
+        mJobFactory.jobs.get(0).fail(ALPHA_DOC);
+        mJobFactory.jobs.get(1).fail(GAMMA_DOC);
 
-        mListener.waitForFinished();
-        mListener.assertFailedCount(1);
-        mListener.assertFileFailed("someDir");
+        mExecutor.runAll();
+        shutdownService();
 
-        assertDestFileCount(0);
+        mExecutor.assertShutdown();
     }
 
-    public void testMoveEmptyDir() throws Exception {
-        String srcPath = "/emptyDir";
-        Uri testDir = createTestDirectory(srcPath);
-
-        Intent moveIntent = createCopyIntent(Lists.newArrayList(testDir));
-        moveIntent.putExtra(FileOperationService.EXTRA_OPERATION, FileOperationService.OPERATION_MOVE);
-        startService(moveIntent);
-
-        // 2 operations: Directory creation, and removal of the original.
-        mResolver.waitForChanges(2);
-
-        assertDestFileCount(1);
-
-        // Verify that the dst exists and is a directory.
-        File dst = mStorage.getFile(DST_ROOT, srcPath);
-        assertTrue(dst.isDirectory());
-
-        // Verify that the src was cleaned up.
-        assertDoesNotExist(SRC_ROOT, srcPath);
-    }
-
-    public void testMovePopulatedDir() throws Exception {
-        String testContent[] = {
-                "The five boxing wizards jump quickly",
-                "The quick brown fox jumps over the lazy dog",
-                "Jackdaws love my big sphinx of quartz"
-        };
-        String srcDir = "/testdir";
-        String srcFiles[] = {
-                srcDir + "/test0.txt",
-                srcDir + "/test1.txt",
-                srcDir + "/test2.txt"
-        };
-        // Create test dir; put some files in it.
-        Uri testDir = createTestDirectory(srcDir);
-        mStorage.createRegularFile(SRC_ROOT, srcFiles[0], "text/plain", testContent[0].getBytes());
-        mStorage.createRegularFile(SRC_ROOT, srcFiles[1], "text/plain", testContent[1].getBytes());
-        mStorage.createRegularFile(SRC_ROOT, srcFiles[2], "text/plain", testContent[2].getBytes());
-
-        Intent moveIntent = createCopyIntent(Lists.newArrayList(testDir));
-        moveIntent.putExtra(FileOperationService.EXTRA_OPERATION, FileOperationService.OPERATION_MOVE);
-        startService(moveIntent);
-
-        // dir creation, then creation and writing of 3 files, then removal of src dir and 3 src
-        // files.
-        mResolver.waitForChanges(11);
-
-        // Check the content of the moved files.
-        File dst = mStorage.getFile(DST_ROOT, srcDir);
-        assertTrue(dst.isDirectory());
-        for (int i = 0; i < testContent.length; ++i) {
-            byte[] dstContent = readFile(DST_ROOT, srcFiles[i]);
-            MoreAsserts.assertEquals("Copied file contents differ", testContent[i].getBytes(),
-                    dstContent);
-        }
-
-        // Check that the src files were removed.
-        assertDoesNotExist(SRC_ROOT, srcDir);
-        for (String srcFile : srcFiles) {
-            assertDoesNotExist(SRC_ROOT, srcFile);
-        }
-    }
-
-    public void testCopyFileWithReadErrors() throws Exception {
-        String srcPath = "/test0.txt";
-        Uri testFile = mStorage.createRegularFile(SRC_ROOT, srcPath, "text/plain",
-                "The five boxing wizards jump quickly".getBytes());
-
-        mStorage.simulateReadErrorsForFile(testFile);
-
-        startService(createCopyIntent(Lists.newArrayList(testFile)));
-
-        // 3 operations: file creation, writing, then deletion (due to failed copy).
-        mResolver.waitForChanges(3);
-
-        // Verify that the failed copy was cleaned up.
-        assertDestFileCount(0);
-    }
-
-    public void testCopyVirtualNonTypedFile() throws Exception {
-        String srcPath = "/non-typed.sth";
-        Uri testFile = mStorage.createVirtualFile(SRC_ROOT, srcPath, "virtual/mime-type",
-                null /* streamTypes */, "I love Tokyo!".getBytes());
-
-        Intent intent = createCopyIntent(Lists.newArrayList(testFile));
-        startService(intent);
-        getService().addFinishedListener(mListener);
-
-        mListener.waitForFinished();
-        mListener.assertFailedCount(1);
-        mListener.assertFileFailed("non-typed.sth");
-        assertDestFileCount(0);
-    }
-
-    public void testMoveFileWithReadErrors() throws Exception {
-        String srcPath = "/test0.txt";
-        Uri testFile = mStorage.createRegularFile(SRC_ROOT, srcPath, "text/plain",
-                "The five boxing wizards jump quickly".getBytes());
-
-        mStorage.simulateReadErrorsForFile(testFile);
-
-        Intent moveIntent = createCopyIntent(Lists.newArrayList(testFile));
-        moveIntent.putExtra(FileOperationService.EXTRA_OPERATION, FileOperationService.OPERATION_MOVE);
-        startService(moveIntent);
-
-        try {
-            // There should be 3 operations: file creation, writing, then deletion (due to failed
-            // copy). Wait for 4, in case the CopyService also attempts to do extra stuff (like
-            // delete the src file). This should time out.
-            mResolver.waitForChanges(4);
-        } catch (TimeoutException e) {
-            // Success path
-            return;
-        } finally {
-            // Verify that the failed copy was cleaned up, and the src file wasn't removed.
-            assertDestFileCount(0);
-            assertExists(SRC_ROOT, srcPath);
-        }
-        // The asserts above didn't fail, but the CopyService did something unexpected.
-        fail("Extra file operations were detected");
-    }
-
-    public void testMoveDirectoryWithReadErrors() throws Exception {
-        String testContent[] = {
-                "The five boxing wizards jump quickly",
-                "The quick brown fox jumps over the lazy dog",
-                "Jackdaws love my big sphinx of quartz"
-        };
-        String srcDir = "/testdir";
-        String srcFiles[] = {
-                srcDir + "/test0.txt",
-                srcDir + "/test1.txt",
-                srcDir + "/test2.txt"
-        };
-        // Create test dir; put some files in it.
-        Uri testDir = createTestDirectory(srcDir);
-        mStorage.createRegularFile(SRC_ROOT, srcFiles[0], "text/plain", testContent[0].getBytes());
-        Uri errFile = mStorage
-                .createRegularFile(SRC_ROOT, srcFiles[1], "text/plain", testContent[1].getBytes());
-        mStorage.createRegularFile(SRC_ROOT, srcFiles[2], "text/plain", testContent[2].getBytes());
-
-        mStorage.simulateReadErrorsForFile(errFile);
-
-        Intent moveIntent = createCopyIntent(Lists.newArrayList(testDir));
-        moveIntent.putExtra(FileOperationService.EXTRA_OPERATION, FileOperationService.OPERATION_MOVE);
-        startService(moveIntent);
-
-        // - dst dir creation,
-        // - creation and writing of 2 files, removal of 2 src files
-        // - creation and writing of 1 file, then removal of that file (due to error)
-        mResolver.waitForChanges(10);
-
-        // Check that both the src and dst dirs exist. The src dir shouldn't have been removed,
-        // because it should contain the one errFile.
-        assertTrue(mStorage.getFile(SRC_ROOT, srcDir).isDirectory());
-        assertTrue(mStorage.getFile(DST_ROOT, srcDir).isDirectory());
-
-        // Check the content of the moved files.
-        MoreAsserts.assertEquals("Copied file contents differ", testContent[0].getBytes(),
-                readFile(DST_ROOT, srcFiles[0]));
-        MoreAsserts.assertEquals("Copied file contents differ", testContent[2].getBytes(),
-                readFile(DST_ROOT, srcFiles[2]));
-
-        // Check that the src files were removed.
-        assertDoesNotExist(SRC_ROOT, srcFiles[0]);
-        assertDoesNotExist(SRC_ROOT, srcFiles[2]);
-
-        // Check that the error file was not copied over.
-        assertDoesNotExist(DST_ROOT, srcFiles[1]);
-        assertExists(SRC_ROOT, srcFiles[1]);
-    }
-
-    private Uri createTestDirectory(String dir) throws IOException {
-        return mStorage.createRegularFile(
-                SRC_ROOT, dir, DocumentsContract.Document.MIME_TYPE_DIR, null);
-    }
-
-    private Intent createCopyIntent(List<Uri> srcs) throws Exception {
-        RootInfo root = mDocHelper.getRoot(DST_ROOT);
-        final Uri dst = DocumentsContract.buildDocumentUri(AUTHORITY, root.documentId);
-
-        return createCopyIntent(srcs, dst);
-    }
-
-    private Intent createCopyIntent(List<Uri> srcs, Uri dst) throws Exception {
-        final ArrayList<DocumentInfo> srcDocs = Lists.newArrayList();
-        for (Uri src : srcs) {
-            srcDocs.add(DocumentInfo.fromUri(mResolver, src));
-        }
-
+    private Intent createCopyIntent(ArrayList<DocumentInfo> files, DocumentInfo dest)
+            throws Exception {
         DocumentStack stack = new DocumentStack();
-        stack.push(DocumentInfo.fromUri(mResolver, dst));
-        final Intent copyIntent = new Intent(mContext, FileOperationService.class);
-        copyIntent.putExtra(
-                FileOperationService.EXTRA_OPERATION,
-                FileOperationService.OPERATION_COPY);
-        copyIntent.putExtra(
-                FileOperationService.EXTRA_JOB_ID,
-                FileOperationService.createJobId());
-        copyIntent.putParcelableArrayListExtra(FileOperationService.EXTRA_SRC_LIST, srcDocs);
-        copyIntent.putExtra(Shared.EXTRA_STACK, (Parcelable) stack);
+        stack.push(dest);
 
-        return copyIntent;
+        return createBaseIntent(OPERATION_COPY, getContext(), createJobId(), files, stack);
     }
 
-    /**
-     * Returns a count of the files in the given directory.
-     */
-    private void assertDestFileCount(int expected) throws RemoteException {
-        RootInfo dest = mDocHelper.getRoot(DST_ROOT);
-        final Uri queryUri = DocumentsContract.buildChildDocumentsUri(AUTHORITY,
-                dest.documentId);
-        Cursor c = null;
-        int count = 0;
-        try {
-            c = mClient.query(queryUri, null, null, null, null);
-            count = c.getCount();
-        } finally {
-            IoUtils.closeQuietly(c);
-        }
-        assertEquals("Incorrect file count after copy", expected, count);
+    private static DocumentInfo createDoc(String name) {
+        // Doesn't need to be valid content Uri, just some urly looking thing.
+        Uri uri = new Uri.Builder()
+                .scheme("content")
+                .authority("com.android.documentsui.testing")
+                .path(name)
+                .build();
+
+        return createDoc(uri);
     }
 
-    private void assertExists(String rootId, String path) throws Exception {
-        assertNotNull("An expected file was not found: " + path + " on root " + rootId,
-                mStorage.getFile(rootId, path));
+    private static DocumentInfo createDoc(Uri destination) {
+        DocumentInfo destDoc = new DocumentInfo();
+        destDoc.derivedUri = destination;
+        return destDoc;
     }
 
-    private void assertDoesNotExist(String rootId, String path) throws Exception {
-        assertNull("Unexpected file found: " + path + " on root " + rootId,
-                mStorage.getFile(rootId, path));
-    }
+    private final class TestJobFactory extends Job.Factory {
 
-    private byte[] readFile(String rootId, String path) throws Exception {
-        File file = mStorage.getFile(rootId, path);
-        byte[] buf = null;
-        assertNotNull(file);
+        final List<TestJob> jobs = new ArrayList<>();
 
-        FileInputStream in = null;
-        try {
-            in = new FileInputStream(file);
-            buf = Streams.readFully(in);
-        } finally {
-            IoUtils.closeQuietly(in);
-        }
-        return buf;
-    }
-
-    private void assertCopied(String path) throws Exception {
-        MoreAsserts.assertEquals("Copied file contents differ", readFile(SRC_ROOT, path),
-                readFile(DST_ROOT, path));
-    }
-
-    /**
-     * Sets up a ContextWrapper that substitutes a stub NotificationManager. This allows the test to
-     * listen for notification events, to gauge copy progress.
-     *
-     * @throws FileNotFoundException
-     */
-    private void setupTestContext() throws FileNotFoundException {
-        mSystemContext = getSystemContext();
-
-        // Set up the context with the test content resolver.
-        mResolver = new TestContentResolver();
-        mContext = new ContextWrapper(mSystemContext) {
-            @Override
-            public ContentResolver getContentResolver() {
-                return mResolver;
-            }
-        };
-        setContext(mContext);
-
-        // Create a local stub provider and add it to the content resolver.
-        ProviderInfo info = new ProviderInfo();
-        info.authority = AUTHORITY;
-        info.exported = true;
-        info.grantUriPermissions = true;
-        info.readPermission = android.Manifest.permission.MANAGE_DOCUMENTS;
-        info.writePermission = android.Manifest.permission.MANAGE_DOCUMENTS;
-
-        mStorage = new StubProvider();
-        mStorage.attachInfo(mContext, info);
-        mResolver.addProvider(AUTHORITY, mStorage);
-    }
-
-    private final class CopyJobListener implements FileOperationService.TestOnlyListener {
-
-        final CountDownLatch latch = new CountDownLatch(1);
-        final List<DocumentInfo> failedDocs = new ArrayList<>();
-
-        @Override
-        public void onFinished(List<DocumentInfo> failed) {
-            failedDocs.addAll(failed);
-            latch.countDown();
-        }
-
-        public void assertFileFailed(String expectedName) {
-            for (DocumentInfo failed : failedDocs) {
-                if (expectedName.equals(failed.displayName)) {
-                    return;
-                }
-            }
-            fail("Couldn't find failed file: " + expectedName);
-        }
-
-        public void waitForFinished() throws InterruptedException {
-            latch.await(500, TimeUnit.MILLISECONDS);
-        }
-
-        public void assertFailedCount(int expected) {
-            assertEquals(expected, failedDocs.size());
-        }
-    }
-
-    /**
-     * A test resolver that enables this test suite to listen for notifications that mark when copy
-     * operations are done.
-     */
-    class TestContentResolver extends MockContentResolver {
-        private CountDownLatch mReadySignal;
-        private CountDownLatch mNotificationSignal;
-
-        public TestContentResolver() {
-            mReadySignal = new CountDownLatch(1);
-        }
-
-        /**
-         * Wait for the given number of files to be copied to destination. Times out after 1 sec.
-         */
-        public void waitForChanges(int count) throws Exception {
-            // Wait for no more than 1 second by default.
-            waitForChanges(count, 1000);
-        }
-
-        /**
-         * Wait for files to be copied to destination.
-         *
-         * @param count Number of files to wait for.
-         * @param timeOut Timeout in ms. TimeoutException will be thrown if this function times out.
-         */
-        public void waitForChanges(int count, int timeOut) throws Exception {
-            mNotificationSignal = new CountDownLatch(count);
-            // Signal that the test is now waiting for files.
-            mReadySignal.countDown();
-            if (!mNotificationSignal.await(timeOut, TimeUnit.MILLISECONDS)) {
-                throw new TimeoutException("Timed out waiting for file operations to complete.");
+        void assertAllJobsStarted() {
+            for (TestJob job : jobs) {
+                job.assertStarted();
             }
         }
 
         @Override
-        public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
-            // Wait until the test is ready to receive file notifications.
-            try {
-                mReadySignal.await();
-            } catch (InterruptedException e) {
-                Log.d(TAG, "Interrupted while waiting for file copy readiness");
-                Thread.currentThread().interrupt();
-            }
-            if (DocumentsContract.isDocumentUri(mContext, uri)) {
-                Log.d(TAG, "Notification: " + uri);
-                // Watch for document URI change notifications - this signifies the end of a copy.
-                mNotificationSignal.countDown();
-            }
+        Job createCopy(Context service, Context appContext, Listener listener, String id,
+                DocumentStack stack, List<DocumentInfo> srcs) {
+            TestJob job = new TestJob(service, appContext, listener, OPERATION_COPY, id, stack);
+            jobs.add(job);
+            return job;
         }
-    };
+    }
 }
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/MoveJobTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/MoveJobTest.java
new file mode 100644
index 0000000..7edfcdb
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/MoveJobTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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.documentsui.services;
+
+import android.test.suitebuilder.annotation.MediumTest;
+
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.DocumentStack;
+
+import java.util.List;
+
+@MediumTest
+public class MoveJobTest extends AbstractCopyJobTest<MoveJob> {
+
+    public void testMoveFiles() throws Exception {
+        runCopyFilesTest();
+
+        mDocs.assertChildCount(mSrcRoot, 0);
+    }
+
+    public void testMoveVirtualTypedFile() throws Exception {
+        runCopyVirtualTypedFileTest();
+
+        mDocs.assertChildCount(mSrcRoot, 0);
+    }
+
+    public void testMoveVirtualNonTypedFile() throws Exception {
+        runCopyVirtualNonTypedFileTest();
+
+        // should have failed, source not deleted
+        mDocs.assertChildCount(mSrcRoot, 1);
+    }
+
+    public void testMoveEmptyDir() throws Exception {
+        runCopyEmptyDirTest();
+
+        mDocs.assertChildCount(mSrcRoot, 0);
+    }
+
+    public void testMoveDirRecursively() throws Exception {
+        runCopyDirRecursivelyTest();
+
+        mDocs.assertChildCount(mSrcRoot, 0);
+    }
+
+    public void testNoMoveDirToSelf() throws Exception {
+        runNoCopyDirToSelfTest();
+
+        // should have failed, source not deleted
+        mDocs.assertChildCount(mSrcRoot, 1);
+    }
+
+    public void testNoMoveDirToDescendent() throws Exception {
+        runNoCopyDirToDescendentTest();
+
+        // should have failed, source not deleted
+        mDocs.assertChildCount(mSrcRoot, 1);
+    }
+
+    public void testMoveFileWithReadErrors() throws Exception {
+        runCopyFileWithReadErrorsTest();
+
+        // should have failed, source not deleted
+        mDocs.assertChildCount(mSrcRoot, 1);
+    }
+
+    @Override
+    MoveJob createJob(List<DocumentInfo> srcs, DocumentStack stack) throws Exception {
+        return new MoveJob(
+                mContext, mContext, mJobListener, FileOperations.createJobId(), stack, srcs);
+    }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestContentResolver.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestContentResolver.java
new file mode 100644
index 0000000..8f39b14
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestContentResolver.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.services;
+
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.provider.DocumentsContract;
+import android.test.mock.MockContentResolver;
+import android.util.Log;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * A test resolver that enables this test suite to listen for notifications that mark when copy
+ * operations are done.
+ */
+class TestContentResolver extends MockContentResolver {
+
+    private static final String TAG = "TestContextResolver";
+
+    private CountDownLatch mReadySignal;
+    private CountDownLatch mNotificationSignal;
+    private Context mContext;
+
+    public TestContentResolver(Context context) {
+        mContext = context;
+        mReadySignal = new CountDownLatch(1);
+    }
+
+    /**
+     * Wait for the given number of files to be copied to destination. Times out after 1 sec.
+     */
+    public void waitForChanges(int count) throws Exception {
+        // Wait for no more than 1 second by default.
+        waitForChanges(count, 1000);
+    }
+
+    /**
+     * Wait for files to be copied to destination.
+     *
+     * @param count Number of files to wait for.
+     * @param timeOut Timeout in ms. TimeoutException will be thrown if this function times out.
+     */
+    public void waitForChanges(int count, int timeOut) throws Exception {
+        mNotificationSignal = new CountDownLatch(count);
+        // Signal that the test is now waiting for files.
+        mReadySignal.countDown();
+        if (!mNotificationSignal.await(timeOut, TimeUnit.MILLISECONDS)) {
+            throw new TimeoutException("Timed out waiting for file operations to complete.");
+        }
+    }
+
+    @Override
+    public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
+        // Wait until the test is ready to receive file notifications.
+        try {
+            mReadySignal.await();
+        } catch (InterruptedException e) {
+            Log.d(TAG, "Interrupted while waiting for file copy readiness");
+            Thread.currentThread().interrupt();
+        }
+        if (DocumentsContract.isDocumentUri(mContext, uri)) {
+            Log.d(TAG, "Notification: " + uri);
+            // Watch for document URI change notifications - this signifies the end of a copy.
+            mNotificationSignal.countDown();
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestJob.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestJob.java
new file mode 100644
index 0000000..9c58780
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestJob.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.services;
+
+import static junit.framework.Assert.assertTrue;
+
+import android.app.Notification;
+import android.app.Notification.Builder;
+import android.content.Context;
+import android.os.RemoteException;
+
+import com.android.documentsui.R;
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.DocumentStack;
+
+public class TestJob extends Job {
+
+    private boolean mStarted;
+
+    TestJob(
+            Context service, Context appContext, Listener listener,
+            int operationType, String id, DocumentStack stack) {
+        super(service, appContext, listener, operationType, id, stack);
+    }
+
+    @Override
+    void start() throws RemoteException {
+        mStarted = true;
+    }
+
+    void assertStarted() {
+        assertTrue(mStarted);
+    }
+
+    void fail(DocumentInfo doc) {
+        onFileFailed(doc);
+    }
+
+    @Override
+    Notification getSetupNotification() {
+        return getSetupNotification(service.getString(R.string.copy_preparing));
+    }
+
+    @Override
+    Notification getFailureNotification() {
+        // the "copy" stuff was just convenient and available :)
+        return getFailureNotification(
+                R.plurals.copy_error_notification_title, R.drawable.ic_menu_copy);
+    }
+
+    @Override
+    Builder createProgressBuilder() {
+        // the "copy" stuff was just convenient and available :)
+        return super.createProgressBuilder(
+                service.getString(R.string.copy_notification_title),
+                R.drawable.ic_menu_copy,
+                service.getString(android.R.string.cancel),
+                R.drawable.ic_cab_cancel);
+    }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestJobListener.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestJobListener.java
new file mode 100644
index 0000000..0110197
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestJobListener.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.services;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import android.support.annotation.Nullable;
+
+import com.android.documentsui.model.DocumentInfo;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class TestJobListener implements Job.Listener {
+
+    private final CountDownLatch latch = new CountDownLatch(1);
+    private final List<Job> progress = new ArrayList<>();
+    @Nullable private Job started;
+    @Nullable private Job failed;
+    @Nullable private Job finished;
+
+    @Override
+    public void onStart(Job job) {
+        started = job;
+    }
+
+    @Override
+    public void onFailed(Job job) {
+        failed = job;
+    }
+
+    @Override
+    public void onFinished(Job job) {
+        this.finished = job;
+        latch.countDown();
+    }
+
+    @Override
+    public void onProgress(CopyJob job) {
+        progress.add(job);
+    }
+
+    public void assertStarted() {
+        if (started == null) {
+            fail("Job didn't start. onStart never called.");
+        }
+    }
+
+    public void assertFinished() {
+        if (finished == null) {
+            fail("Job didn't finish. onFinish never called.");
+        }
+    }
+
+    public void assertFailed() {
+        if (failed == null) {
+            fail("Job didn't fail. onFailed never called.");
+        }
+    }
+
+    public void assertFilesFailed(ArrayList<String> names) {
+        if (failed == null) {
+            fail("Can't test failed documetns. Job didn't fail.");
+        }
+
+        assertEquals(failed.failedFiles.size(), names.size());
+        for (String name : names) {
+            assertFileFailed(name);
+        }
+    }
+
+    public void assertFileFailed(String name) {
+        if (failed == null) {
+            fail("Can't test failed documetns. Job didn't fail.");
+        }
+
+        for (DocumentInfo failed : failed.failedFiles) {
+            if (name.equals(failed.displayName)) {
+                return;
+            }
+        }
+        fail("Couldn't find failed file: " + name);
+    }
+
+    public void assertCanceled() {
+        if (finished == null) {
+            fail("Can't determine if job was canceled. Job didn't finish.");
+        }
+        if (!finished.isCanceled()) {
+            fail("Job wasn't canceled. Job#isCanceled returned false.");
+        }
+    }
+
+    public void assertMadeProgress() {
+        if (progress.isEmpty()) {
+            fail("Job made no progress. onProgress never called.");
+        }
+    }
+
+    public void waitForFinished() throws InterruptedException {
+        latch.await(500, TimeUnit.MILLISECONDS);
+    }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestScheduledExecutorService.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestScheduledExecutorService.java
new file mode 100644
index 0000000..4d417cf
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestScheduledExecutorService.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.services;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+public class TestScheduledExecutorService implements ScheduledExecutorService {
+
+    private List<TestFuture> scheduled = new ArrayList<>();
+    private boolean shutdown;
+
+    @Override
+    public void shutdown() {
+        this.shutdown = true;
+    }
+
+    @Override
+    public List<Runnable> shutdownNow() {
+        this.shutdown = true;
+        return new ArrayList<>();
+    }
+
+    void assertShutdown() {
+        if (!shutdown) {
+            fail("Executor wasn't shut down.");
+        }
+    }
+
+    @Override
+    public boolean isShutdown() {
+        return shutdown;
+    }
+
+    @Override
+    public boolean isTerminated() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public <T> Future<T> submit(Callable<T> task) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public <T> Future<T> submit(Runnable task, T result) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Future<?> submit(Runnable task) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
+            throws InterruptedException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout,
+            TimeUnit unit) throws InterruptedException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
+            throws InterruptedException, ExecutionException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
+            throws InterruptedException, ExecutionException, TimeoutException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void execute(Runnable command) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
+        TestFuture future = new TestFuture(command, delay, unit);
+        scheduled.add(future);
+        return future;
+    }
+
+    @Override
+    public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period,
+            TimeUnit unit) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay,
+            long delay, TimeUnit unit) {
+        throw new UnsupportedOperationException();
+    }
+
+    void runAll() {
+        for (TestFuture future : scheduled) {
+            future.runnable.run();
+        }
+    }
+
+    void run(int taskIndex) {
+        scheduled.get(taskIndex).runnable.run();
+    }
+
+    public void assertAlive() {
+        assertFalse(isShutdown());
+    }
+
+    static class TestFuture implements ScheduledFuture<Void> {
+
+        final Runnable runnable;
+        final long delay;
+        final TimeUnit unit;
+
+        public TestFuture(Runnable runnable, long delay, TimeUnit unit) {
+            this.runnable = runnable;
+            this.delay = delay;
+            this.unit = unit;
+        }
+
+        @Override
+        public long getDelay(TimeUnit unit) {
+            return 0;
+        }
+
+        @Override
+        public int compareTo(Delayed arg0) {
+            return 0;
+        }
+
+        @Override
+        public boolean cancel(boolean mayInterruptIfRunning) {
+            return false;
+        }
+
+        @Override
+        public boolean isCancelled() {
+            return false;
+        }
+
+        @Override
+        public boolean isDone() {
+            return false;
+        }
+
+        @Override
+        public Void get() throws InterruptedException, ExecutionException {
+            return null;
+        }
+
+        @Override
+        public Void get(long timeout, TimeUnit unit)
+                throws InterruptedException, ExecutionException, TimeoutException {
+            return null;
+        }
+    }
+}
diff --git a/packages/Keyguard/res/values-am/strings.xml b/packages/Keyguard/res/values-am/strings.xml
index 8c5bb9d..2b19d7a 100644
--- a/packages/Keyguard/res/values-am/strings.xml
+++ b/packages/Keyguard/res/values-am/strings.xml
@@ -110,9 +110,9 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"ከአገልግሎት መስጫ ክልል ውጪ።"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"የግቤት ስልት አዝራር ቀይር"</string>
     <string name="airplane_mode" msgid="3122107900897202805">"የአውሮፕላን ሁነታ"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"መሣሪያ ዳግም ከተጀመረ በኋላ ሥርዓተ ጥለት ያስፈልጋል"</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"መሣሪያ ዳግም ከተጀመረ በኋላ ፒን ያስፈልጋል"</string>
-    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"መሣሪያ ዳግም ከተጀመረ በኋላ የይለፍ ቃል ያስፈልጋል"</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"መሣሪያ ዳግም ከጀመረ በኋላ ሥርዓተ ጥለት ያስፈልጋል"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"መሣሪያ ዳግም ከጀመረ በኋላ ፒን ያስፈልጋል"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"መሣሪያ ዳግም ከጀመረ በኋላ የይለፍ ቃል ያስፈልጋል"</string>
     <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"ሥርዓተ ጥለት ለተጨማሪ ደህንነት ያስፈልጋል"</string>
     <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"ፒን ለተጨማሪ ደህንነት ያስፈልጋል"</string>
     <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"የይለፍ ቃል ለተጨማሪ ደህንነት ያስፈልጋል"</string>
diff --git a/packages/Keyguard/res/values-eu-rES/strings.xml b/packages/Keyguard/res/values-eu-rES/strings.xml
index 525b028..1c834e9 100644
--- a/packages/Keyguard/res/values-eu-rES/strings.xml
+++ b/packages/Keyguard/res/values-eu-rES/strings.xml
@@ -110,7 +110,7 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Zerbitzurik gabe."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Idazketa-metodoa aldatzeko botoia."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Hegaldi modua"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Eredua marraztu beharko duzu da gailua berrabiarazten denean"</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Eredua marraztu beharko duzu gailua berrabiarazten denean"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"PIN kodea idatzi beharko duzu gailua berrabiarazten denean"</string>
     <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Pasahitza idatzi beharko duzu gailua berrabiarazten denean"</string>
     <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Segurtasun handiagoa izateko, eredua behar da"</string>
diff --git a/packages/Keyguard/res/values-ky-rKG/strings.xml b/packages/Keyguard/res/values-ky-rKG/strings.xml
index 04c4942..5403c71 100644
--- a/packages/Keyguard/res/values-ky-rKG/strings.xml
+++ b/packages/Keyguard/res/values-ky-rKG/strings.xml
@@ -110,15 +110,15 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"Байланыш жок."</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Киргизүү ыкмасын которуу баскычы."</string>
     <string name="airplane_mode" msgid="3122107900897202805">"Учак режими"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Түзмөк кайра күйгүзүлгөндөн кийин графикалык ачкыч керектелет"</string>
-    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Түзмөк кайра күйгүзүлгөндөн кийин PIN код керектелет"</string>
-    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Түзмөк кайра күйгүзүлгөндөн кийин сырсөз керектелет"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Кошумча коопсуздук үчүн графикалык ачкыч керектелет"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Кошумча коопсуздук үчүн PIN код керектелет"</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Кошумча коопсуздук үчүн сырсөз керектелет"</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Профилдерди которгонуңузда графикалык ачкыч керектелет"</string>
-    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Профилдерди которгонуңузда PIN код керектелет"</string>
-    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Профилдерди которгонуңузда сырсөз керектелет"</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"Түзмөк кайра күйгүзүлгөндөн кийин графикалык ачкыч талап кылынат"</string>
+    <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"Түзмөк кайра күйгүзүлгөндөн кийин PIN код талап кылынат"</string>
+    <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"Түзмөк кайра күйгүзүлгөндөн кийин сырсөз талап кылынат"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Коопсуздукту бекемдөө үчүн графикалык ачкыч талап кылынат"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Коопсуздукту бекемдөө үчүн PIN код талап кылынат"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Коопсуздукту бекемдөө үчүн сырсөз талап кылынат"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"Профилдерди которуштурганда графикалык ачкыч талап кылынат"</string>
+    <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"Профилдерди которуштурганда PIN код талап кылынат"</string>
+    <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"Профилдерди которуштурганда сырсөз талап кылынат"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
       <item quantity="other">Түзмөктүн кулпусу <xliff:g id="NUMBER_1">%d</xliff:g> саат бою ачылган жок. Cүрөт үлгүсүн ырастаңыз.</item>
       <item quantity="one">Түзмөктүн кулпусу <xliff:g id="NUMBER_0">%d</xliff:g> саат бою ачылган жок. Cүрөт үлгүсүн ырастаңыз.</item>
diff --git a/packages/Keyguard/res/values-pt-rPT/strings.xml b/packages/Keyguard/res/values-pt-rPT/strings.xml
index 8cc9e5b..49c2f16 100644
--- a/packages/Keyguard/res/values-pt-rPT/strings.xml
+++ b/packages/Keyguard/res/values-pt-rPT/strings.xml
@@ -113,9 +113,9 @@
     <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"É necessário um padrão após reiniciar o dispositivo"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"É necessário um PIN após reiniciar o dispositivo"</string>
     <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"É necessária uma palavra-passe após reiniciar o dispositivo"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Para uma segurança adicional, é necessário um padrão"</string>
-    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Para uma segurança adicional, é necessária um PIN"</string>
-    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Para uma segurança adicional, é necessária uma palavra-passe"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"Para segurança adicional, é necessário um padrão"</string>
+    <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"Para segurança adicional, é necessária um PIN"</string>
+    <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"Para segurança adicional, é necessária uma palavra-passe"</string>
     <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"É necessário um padrão quando muda de perfil"</string>
     <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"É necessário um PIN quando muda de perfil"</string>
     <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"É necessária uma palavra-passe quando muda de perfil"</string>
diff --git a/packages/Keyguard/res/values-zh-rTW/strings.xml b/packages/Keyguard/res/values-zh-rTW/strings.xml
index d0d428b..0cb4b16 100644
--- a/packages/Keyguard/res/values-zh-rTW/strings.xml
+++ b/packages/Keyguard/res/values-zh-rTW/strings.xml
@@ -46,7 +46,7 @@
     <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM 卡處於鎖定狀態。"</string>
     <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM 卡處於 PUK 鎖定狀態"</string>
     <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"正在解除 SIM 卡鎖定..."</string>
-    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"圖形解鎖。"</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"圖案解鎖。"</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN 解鎖。"</string>
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"密碼解鎖。"</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"圖形區域。"</string>
@@ -79,7 +79,7 @@
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"圖形嘗試次數過多"</string>
     <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"您的 PIN 已輸錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
     <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"您的密碼已輸錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"您的解鎖圖案已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%2$d</xliff:g> 秒後再試一次。"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="8774056606869646621">"您嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,這台平板電腦將會重設,其中的所有資料也會一併遭到刪除。"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="1843331751334128428">"您嘗試解鎖手機已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,系統會重設您的手機,其中的所有資料也會一併遭到刪除。"</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="258925501999698032">"您嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。這台平板電腦將會重設,其中的所有資料也會一併遭到刪除。"</string>
@@ -92,8 +92,8 @@
     <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="6853071165802933545">"您嘗試解鎖手機已失敗 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,您的 Work 設定檔將遭到移除,所有設定檔資料也會一併遭到刪除。"</string>
     <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4686386497449912146">"您嘗試解鎖平板電腦已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。您的 Work 設定檔將遭到移除,所有設定檔資料也會一併遭到刪除。"</string>
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4951507352869831265">"您嘗試解鎖手機已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。您的 Work 設定檔將遭到移除,所有設定檔資料也會一併遭到刪除。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除平板電腦的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除手機的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"您的解鎖圖案已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除平板電腦的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您的解鎖圖案已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除手機的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"SIM 卡的 PIN 碼輸入錯誤,您現在必須請行動通訊業者為裝置解鎖。"</string>
     <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="6721575017538162249">
       <item quantity="other">SIM 卡的 PIN 碼輸入錯誤,您還可以再試 <xliff:g id="NUMBER_1">%d</xliff:g> 次。</item>
@@ -110,18 +110,18 @@
     <string name="keyguard_carrier_default" msgid="8700650403054042153">"沒有服務。"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"切換輸入法按鈕。"</string>
     <string name="airplane_mode" msgid="3122107900897202805">"飛航模式"</string>
-    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"裝置重新啟動後需要畫出解鎖圖形"</string>
+    <string name="kg_prompt_reason_restart_pattern" msgid="5519822969283306009">"裝置重新啟動後需要畫出解鎖圖案"</string>
     <string name="kg_prompt_reason_restart_pin" msgid="4411398237158448198">"裝置重新啟動後需要輸入 PIN 碼"</string>
     <string name="kg_prompt_reason_restart_password" msgid="6504585392626524695">"裝置重新啟動後需要輸入密碼"</string>
-    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"請畫出解鎖圖形,以進一步確保資訊安全"</string>
+    <string name="kg_prompt_reason_timeout_pattern" msgid="3717506169674397620">"請畫出解鎖圖案,以進一步確保資訊安全"</string>
     <string name="kg_prompt_reason_timeout_pin" msgid="6951483704195396341">"請輸入 PIN 碼,以進一步確保資訊安全"</string>
     <string name="kg_prompt_reason_timeout_password" msgid="7306667546971345027">"請輸入密碼,以進一步確保資訊安全"</string>
-    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"切換設定檔時需要畫出解鎖圖形"</string>
+    <string name="kg_prompt_reason_switch_profiles_pattern" msgid="8476293962695171574">"切換設定檔時需要畫出解鎖圖案"</string>
     <string name="kg_prompt_reason_switch_profiles_pin" msgid="2343607138520460043">"切換設定檔時需要輸入 PIN 碼"</string>
     <string name="kg_prompt_reason_switch_profiles_password" msgid="1295960907951965927">"切換設定檔時需要輸入密碼"</string>
     <plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="2697444392228541853">
-      <item quantity="other">裝置已有 <xliff:g id="NUMBER_1">%d</xliff:g> 小時未解鎖。請確認圖形。</item>
-      <item quantity="one">裝置已有 <xliff:g id="NUMBER_0">%d</xliff:g> 小時未解鎖。請確認圖形。</item>
+      <item quantity="other">裝置已有 <xliff:g id="NUMBER_1">%d</xliff:g> 小時未解鎖。請確認圖案。</item>
+      <item quantity="one">裝置已有 <xliff:g id="NUMBER_0">%d</xliff:g> 小時未解鎖。請確認圖案。</item>
     </plurals>
     <plurals name="kg_prompt_reason_time_pin" formatted="false" msgid="2118758475374354849">
       <item quantity="other">裝置已有 <xliff:g id="NUMBER_1">%d</xliff:g> 小時未解鎖。請確認 PIN 碼。</item>
diff --git a/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp b/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp
index cde28fc..66a3247 100644
--- a/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp
+++ b/packages/MtpDocumentsProvider/jni/com_android_mtp_AppFuse.cpp
@@ -31,6 +31,7 @@
 #include "JNIHelp.h"
 #include "android_runtime/AndroidRuntime.h"
 #include "nativehelper/ScopedPrimitiveArray.h"
+#include "nativehelper/ScopedLocalRef.h"
 
 namespace {
 
@@ -334,16 +335,16 @@
         const uint32_t read_size = static_cast<uint32_t>(std::min(
                 static_cast<uint64_t>(size),
                 get_file_size(inode) - offset));
-        const jbyteArray array = (jbyteArray) env_->CallObjectMethod(
+        ScopedLocalRef<jbyteArray> array(env_, static_cast<jbyteArray>(env_->CallObjectMethod(
                 self_,
                 app_fuse_get_object_bytes,
                 inode,
                 offset,
-                read_size);
-        if (array == nullptr) {
+                read_size)));
+        if (array.get() == nullptr) {
             return -1;
         }
-        ScopedByteArrayRO bytes(env_, array);
+        ScopedByteArrayRO bytes(env_, array.get());
         if (bytes.size() != read_size || bytes.get() == nullptr) {
             return -1;
         }
@@ -379,7 +380,7 @@
 
 jboolean com_android_mtp_AppFuse_start_app_fuse_loop(
         JNIEnv* env, jobject self, jint jfd) {
-    ScopedFd fd(dup(static_cast<int>(jfd)));
+    ScopedFd fd(static_cast<int>(jfd));
     AppFuse appfuse(env, self);
 
     ALOGD("Start fuse loop.");
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java b/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java
index 01d1301..1300c47 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/AppFuse.java
@@ -21,6 +21,7 @@
 import android.os.storage.StorageManager;
 import android.util.Log;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.Preconditions;
 import com.android.mtp.annotations.UsedByNative;
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -39,22 +40,18 @@
 
     private final String mName;
     private final Callback mCallback;
-    private final Thread mMessageThread;
+    private Thread mMessageThread;
     private ParcelFileDescriptor mDeviceFd;
 
     AppFuse(String name, Callback callback) {
         mName = name;
         mCallback = callback;
-        mMessageThread = new Thread(new Runnable() {
-            @Override
-            public void run() {
-                native_start_app_fuse_loop(mDeviceFd.getFd());
-            }
-        });
     }
 
-    void mount(StorageManager storageManager) {
+    void mount(StorageManager storageManager) throws IOException {
+        Preconditions.checkState(mDeviceFd == null);
         mDeviceFd = storageManager.mountAppFuse(mName);
+        mMessageThread = new AppFuseMessageThread(mDeviceFd.dup().detachFd());
         mMessageThread.start();
     }
 
@@ -80,7 +77,6 @@
                 ParcelFileDescriptor.MODE_READ_ONLY);
     }
 
-    @VisibleForTesting
     File getMountPoint() {
         return new File("/mnt/appfuse/" + Process.myUid() + "_" + mName);
     }
@@ -112,4 +108,22 @@
     }
 
     private native boolean native_start_app_fuse_loop(int fd);
+
+    private class AppFuseMessageThread extends Thread {
+        /**
+         * File descriptor used by native loop.
+         * It's owned by native loop and does not need to close here.
+         */
+        private final int mRawFd;
+
+        AppFuseMessageThread(int fd) {
+            super("AppFuseMessageThread");
+            mRawFd = fd;
+        }
+
+        @Override
+        public void run() {
+            native_start_app_fuse_loop(mRawFd);
+        }
+    }
 }
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
index afef3de..3381656 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
@@ -92,7 +92,12 @@
         mRootScanner = new RootScanner(mResolver, mResources, mMtpManager, mDatabase);
         mAppFuse = new AppFuse(TAG, new AppFuseCallback());
         // TODO: Mount AppFuse on demands.
-        mAppFuse.mount(getContext().getSystemService(StorageManager.class));
+        try {
+            mAppFuse.mount(getContext().getSystemService(StorageManager.class));
+        } catch (IOException e) {
+            Log.e(TAG, "Failed to start app fuse.", e);
+            return false;
+        }
         resume();
         return true;
     }
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/AppFuseTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/AppFuseTest.java
index 5e1a796..6354880 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/AppFuseTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/AppFuseTest.java
@@ -30,7 +30,7 @@
 
 @MediumTest
 public class AppFuseTest extends AndroidTestCase {
-    public void testMount() throws ErrnoException {
+    public void testMount() throws ErrnoException, IOException {
         final StorageManager storageManager = getContext().getSystemService(StorageManager.class);
         final AppFuse appFuse = new AppFuse("test", new TestCallback());
         appFuse.mount(storageManager);
@@ -61,7 +61,7 @@
         appFuse.close();
     }
 
-    public void testOpenFile_error() {
+    public void testOpenFile_fileNotFound() throws IOException {
         final StorageManager storageManager = getContext().getSystemService(StorageManager.class);
         final int INODE = 10;
         final AppFuse appFuse = new AppFuse("test", new TestCallback());
diff --git a/packages/PrintSpooler/res/values-de/strings.xml b/packages/PrintSpooler/res/values-de/strings.xml
index d925ddb..bcb7e73 100644
--- a/packages/PrintSpooler/res/values-de/strings.xml
+++ b/packages/PrintSpooler/res/values-de/strings.xml
@@ -76,7 +76,7 @@
     <string name="reason_unknown" msgid="5507940196503246139">"unbekannt"</string>
     <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nicht verfügbar"</string>
     <string name="print_service_security_warning_title" msgid="2160752291246775320">"<xliff:g id="SERVICE">%1$s</xliff:g> verwenden?"</string>
-    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Ihr Dokument passiert bei der Übermittlung an den Drucker möglicherweise einen oder mehrere Server."</string>
+    <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Dein Dokument passiert bei der Übermittlung an den Drucker möglicherweise einen oder mehrere Server."</string>
   <string-array name="color_mode_labels">
     <item msgid="7602948745415174937">"Schwarz-weiß"</item>
     <item msgid="2762241247228983754">"Farbe"</item>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java
index 13105aa..1aec253 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java
@@ -635,9 +635,9 @@
             CharSequence description = printer.getDescription();
 
             CharSequence subtitle;
-            if (printServiceLabel == null) {
+            if (TextUtils.isEmpty(printServiceLabel)) {
                 subtitle = description;
-            } else if (description == null) {
+            } else if (TextUtils.isEmpty(description)) {
                 subtitle = printServiceLabel;
             } else {
                 subtitle = getString(R.string.printer_extended_description_template,
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index e04adde..f768dc3 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -72,7 +72,7 @@
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Pairing durchführen"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"Pairing durchführen"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Abbrechen"</string>
-    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Über das Pairing kann auf Ihre Kontakte und auf Ihren Anrufverlauf zugegriffen werden, wenn eine Verbindung besteht."</string>
+    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Über das Pairing kann auf deine Kontakte und auf deinen Anrufverlauf zugegriffen werden, wenn eine Verbindung besteht."</string>
     <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Pairing mit <xliff:g id="DEVICE_NAME">%1$s</xliff:g> war nicht möglich."</string>
     <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Pairing mit <xliff:g id="DEVICE_NAME">%1$s</xliff:g> war nicht möglich, weil die eingegebene PIN oder der Zugangscode falsch ist."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Kommunikation mit <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ist nicht möglich."</string>
diff --git a/packages/SettingsLib/res/values-eu-rES/strings.xml b/packages/SettingsLib/res/values-eu-rES/strings.xml
index 145e8f8..64a1410 100644
--- a/packages/SettingsLib/res/values-eu-rES/strings.xml
+++ b/packages/SettingsLib/res/values-eu-rES/strings.xml
@@ -277,7 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Automatikoa"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView implementation"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Set WebView implementation"</string>
-    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Desgaituta dago aukeratu den Web-ikustailearen inplementazioa. Erabili nahi izanez gero, gaitu egin behar duzu. Gaitu nahi al duzu?"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Desgaituta dago aukeratu den WebView inplementazioa. Erabili nahi izanez gero, gaitu egin behar duzu. Gaitu nahi al duzu?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Eman fitxategietan oinarritutako enkriptatzea"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Enkriptatu…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Fitxategietan oinarritutako enkriptatzea dauka dagoeneko"</string>
diff --git a/packages/SettingsLib/res/values-ky-rKG/strings.xml b/packages/SettingsLib/res/values-ky-rKG/strings.xml
index 4bb625c..fcd7b8f 100644
--- a/packages/SettingsLib/res/values-ky-rKG/strings.xml
+++ b/packages/SettingsLib/res/values-ky-rKG/strings.xml
@@ -277,7 +277,7 @@
     <string name="night_mode_auto" msgid="7508348175804304327">"Автоматтык"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"WebView аткарылышы"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView аткарылышын коюу"</string>
-    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"Тандалган WebView аткаруу функциясы өчүрүлдү жана аны колдонуу үчүн иштетилиши керек, аны иштетет белеңиз?"</string>
+    <string name="select_webview_provider_confirmation_text" msgid="6671472080671066972">"WebView кызматын пайдалануу үчүн аны иштетүү керек. Иштетесизби?"</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"Файл шифрлөөсүнө айландыруу"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Айландыруу…"</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Файл мурунтан эле шифрленген"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
index ca0eda5f..d69250b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
@@ -128,15 +128,17 @@
         boolean isDisabledByMultipleAdmins = false;
         ComponentName adminComponent = null;
         List<ComponentName> admins = dpm.getActiveAdmins();
-        int disabledKeyguardFeatures;
-        for (ComponentName admin : admins) {
-            disabledKeyguardFeatures = dpm.getKeyguardDisabledFeatures(admin);
-            if ((disabledKeyguardFeatures & keyguardNotificationFeatures) != 0) {
-                if (adminComponent == null) {
-                    adminComponent = admin;
-                } else {
-                    isDisabledByMultipleAdmins = true;
-                    break;
+        if (admins != null) {
+            int disabledKeyguardFeatures;
+            for (ComponentName admin : admins) {
+                disabledKeyguardFeatures = dpm.getKeyguardDisabledFeatures(admin);
+                if ((disabledKeyguardFeatures & keyguardNotificationFeatures) != 0) {
+                    if (adminComponent == null) {
+                        adminComponent = admin;
+                    } else {
+                        isDisabledByMultipleAdmins = true;
+                        break;
+                    }
                 }
             }
         }
@@ -242,14 +244,16 @@
         ComponentName adminComponent = null;
         List<ComponentName> admins = dpm.getActiveAdmins();
         int quality;
-        for (ComponentName admin : admins) {
-            quality = dpm.getPasswordQuality(admin);
-            if (quality >= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
-                if (adminComponent == null) {
-                    adminComponent = admin;
-                } else {
-                    isDisabledByMultipleAdmins = true;
-                    break;
+        if (admins != null) {
+            for (ComponentName admin : admins) {
+                quality = dpm.getPasswordQuality(admin);
+                if (quality >= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
+                    if (adminComponent == null) {
+                        adminComponent = admin;
+                    } else {
+                        isDisabledByMultipleAdmins = true;
+                        break;
+                    }
                 }
             }
         }
@@ -430,4 +434,4 @@
             other.userId = userId;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/Shell/res/values-af/strings.xml b/packages/Shell/res/values-af/strings.xml
index 247ccfc..d11a499 100644
--- a/packages/Shell/res/values-af/strings.xml
+++ b/packages/Shell/res/values-af/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Skermkiekie suksesvol geneem."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Kon nie skermkiekie neem nie."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Foutverslagbesonderhede"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Kort naam"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"1-reëlopsomming"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Gedetailleerde beskrywing"</string>
 </resources>
diff --git a/packages/Shell/res/values-am/strings.xml b/packages/Shell/res/values-am/strings.xml
index 9f3615a..cfa22ff 100644
--- a/packages/Shell/res/values-am/strings.xml
+++ b/packages/Shell/res/values-am/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"ቅጽበታዊ ገጽ እይታ በስኬት ተነስቷል።"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ቅጽበታዊ ገጽ እይታ ሊነሳ አይችልም"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"የሳንካ ሪፖርት ዝርዝሮች"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"አጭር ስም"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"የ1 መስመር ማጠቃለያ"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"ዝርዝር መግለጫ"</string>
 </resources>
diff --git a/packages/Shell/res/values-ar/strings.xml b/packages/Shell/res/values-ar/strings.xml
index b670e37..dc8edba 100644
--- a/packages/Shell/res/values-ar/strings.xml
+++ b/packages/Shell/res/values-ar/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"تم التقاط لقطة الشاشة بنجاح."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"تعذر التقاط لقطة الشاشة."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"تفاصيل تقرير الخطأ"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"اسم مختصر"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"سطر الملخص الأول"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"وصف تفصيلي"</string>
 </resources>
diff --git a/packages/Shell/res/values-az-rAZ/strings.xml b/packages/Shell/res/values-az-rAZ/strings.xml
index 634d123..b47edc8 100644
--- a/packages/Shell/res/values-az-rAZ/strings.xml
+++ b/packages/Shell/res/values-az-rAZ/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Displey görüntüsü uğurla çəkildi."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Displey görüntüsü əlçatan deyil."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Baq hesabat detalları"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Qısa ad"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"1-sətrlik xülasə"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Ətraflı təsvir"</string>
 </resources>
diff --git a/packages/Shell/res/values-b+sr+Latn/strings.xml b/packages/Shell/res/values-b+sr+Latn/strings.xml
index 41acb89..16f1d28 100644
--- a/packages/Shell/res/values-b+sr+Latn/strings.xml
+++ b/packages/Shell/res/values-b+sr+Latn/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Snimanje ekrana je uspelo."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Snimanje ekrana nije uspelo."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalji izveštaja o grešci"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Kratki naziv"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Rezime u jednom redu"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detaljni opis"</string>
 </resources>
diff --git a/packages/Shell/res/values-bg/strings.xml b/packages/Shell/res/values-bg/strings.xml
index 661a0b65..ae60f0b 100644
--- a/packages/Shell/res/values-bg/strings.xml
+++ b/packages/Shell/res/values-bg/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Екранната снимка бе направена успешно."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Екранната снимка не можа да бъде направена."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Подробности за сигнала за програмна грешка"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Кратко име"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Едноредово обобщение"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Подробно описание"</string>
 </resources>
diff --git a/packages/Shell/res/values-bn-rBD/strings.xml b/packages/Shell/res/values-bn-rBD/strings.xml
index e7256ca..1192275 100644
--- a/packages/Shell/res/values-bn-rBD/strings.xml
+++ b/packages/Shell/res/values-bn-rBD/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"স্ক্রীনশট সফলভাবে নেওয়া হয়েছে৷"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"স্ক্রীনশট নেওয়া যায়নি৷"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ত্রুটি প্রতিবেদনের বিবরণ"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"ছোট নাম"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"১-লাইনের সারসংক্ষেপ"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"বিস্তারিত বিবরণ"</string>
 </resources>
diff --git a/packages/Shell/res/values-ca/strings.xml b/packages/Shell/res/values-ca/strings.xml
index a8c9553..abf8a6d 100644
--- a/packages/Shell/res/values-ca/strings.xml
+++ b/packages/Shell/res/values-ca/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"La captura de pantalla s\'ha fet correctament."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"No s\'ha pogut fer la captura de pantalla."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalls de l\'informe d\'errors"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Nom curt"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Resum d\'una línia"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Descripció detallada"</string>
 </resources>
diff --git a/packages/Shell/res/values-cs/strings.xml b/packages/Shell/res/values-cs/strings.xml
index 193501e2..b19f50a 100644
--- a/packages/Shell/res/values-cs/strings.xml
+++ b/packages/Shell/res/values-cs/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Snímek obrazovky byl úspěšně pořízen."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Snímek obrazovky se nepodařilo pořídit."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Podrobnosti zprávy o chybě"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Krátký název"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Shrnutí na jeden řádek"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Podrobný popis"</string>
 </resources>
diff --git a/packages/Shell/res/values-da/strings.xml b/packages/Shell/res/values-da/strings.xml
index 3975800..df2ba6f 100644
--- a/packages/Shell/res/values-da/strings.xml
+++ b/packages/Shell/res/values-da/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Der blev taget et skærmbillede."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Der kunne ikke tages et skærmbillede."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Fejlrapportoplysninger"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Kort navn"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Sammenfatning på én linje"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detaljeret beskrivelse"</string>
 </resources>
diff --git a/packages/Shell/res/values-de/strings.xml b/packages/Shell/res/values-de/strings.xml
index eaf67f5..b1dab44 100644
--- a/packages/Shell/res/values-de/strings.xml
+++ b/packages/Shell/res/values-de/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Screenshot wurde aufgenommen."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Screenshot konnte nicht aufgenommen werden."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Details des Fehlerberichts"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Kurzname"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Zusammenfassung in einer Zeile"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detaillierte Beschreibung"</string>
 </resources>
diff --git a/packages/Shell/res/values-el/strings.xml b/packages/Shell/res/values-el/strings.xml
index ec5f3ac..700869b 100644
--- a/packages/Shell/res/values-el/strings.xml
+++ b/packages/Shell/res/values-el/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Η λήψη του στιγμιότυπου οθόνης ολοκληρώθηκε με επιτυχία."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Δεν ήταν δυνατή η λήψη του στιγμιότυπου οθόνης."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Λεπτομέρειες αναφοράς σφαλμάτων"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Υποκοριστικό"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Σύνοψη μίας σειράς"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Αναλυτική περιγραφή"</string>
 </resources>
diff --git a/packages/Shell/res/values-en-rAU/strings.xml b/packages/Shell/res/values-en-rAU/strings.xml
index 26a3d38..dd97cda3 100644
--- a/packages/Shell/res/values-en-rAU/strings.xml
+++ b/packages/Shell/res/values-en-rAU/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Screenshot taken successfully."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Screenshot could not be taken."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Bug report details"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Short name"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"1-line summary"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detailed description"</string>
 </resources>
diff --git a/packages/Shell/res/values-en-rGB/strings.xml b/packages/Shell/res/values-en-rGB/strings.xml
index 26a3d38..dd97cda3 100644
--- a/packages/Shell/res/values-en-rGB/strings.xml
+++ b/packages/Shell/res/values-en-rGB/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Screenshot taken successfully."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Screenshot could not be taken."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Bug report details"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Short name"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"1-line summary"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detailed description"</string>
 </resources>
diff --git a/packages/Shell/res/values-en-rIN/strings.xml b/packages/Shell/res/values-en-rIN/strings.xml
index 26a3d38..dd97cda3 100644
--- a/packages/Shell/res/values-en-rIN/strings.xml
+++ b/packages/Shell/res/values-en-rIN/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Screenshot taken successfully."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Screenshot could not be taken."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Bug report details"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Short name"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"1-line summary"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detailed description"</string>
 </resources>
diff --git a/packages/Shell/res/values-es-rUS/strings.xml b/packages/Shell/res/values-es-rUS/strings.xml
index 7f70feb..3fdf639 100644
--- a/packages/Shell/res/values-es-rUS/strings.xml
+++ b/packages/Shell/res/values-es-rUS/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Se tomó la captura de pantalla correctamente."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"No se pudo tomar la captura de pantalla."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalles del informe de errores"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Nombre corto"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Resumen de una línea"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Descripción completa"</string>
 </resources>
diff --git a/packages/Shell/res/values-es/strings.xml b/packages/Shell/res/values-es/strings.xml
index df080d2..2faa948 100644
--- a/packages/Shell/res/values-es/strings.xml
+++ b/packages/Shell/res/values-es/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"La captura de pantalla se ha realizado correctamente."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"No se puede realizar la captura de pantalla."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalles del informe de errores"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Nombre corto"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Resumen de 1 línea"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Descripción completa"</string>
 </resources>
diff --git a/packages/Shell/res/values-et-rEE/strings.xml b/packages/Shell/res/values-et-rEE/strings.xml
index 94b4b89..1d59b75 100644
--- a/packages/Shell/res/values-et-rEE/strings.xml
+++ b/packages/Shell/res/values-et-rEE/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Ekraanipildi tegemine õnnestus."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Ekraanipilti ei saanud teha."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Veaaruande üksikasjad"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Lühike nimi"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"1-realine kokkuvõte"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Üksikasjalik kirjeldus"</string>
 </resources>
diff --git a/packages/Shell/res/values-eu-rES/strings.xml b/packages/Shell/res/values-eu-rES/strings.xml
index cad55fc..e85b8cd 100644
--- a/packages/Shell/res/values-eu-rES/strings.xml
+++ b/packages/Shell/res/values-eu-rES/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Atera da pantaila-argazkia."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Ezin izan da atera pantaila-argazkia."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Akatsen txostenaren xehetasunak"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Izen laburra"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Lerro bakarreko laburpena"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Azalpen xehatua"</string>
 </resources>
diff --git a/packages/Shell/res/values-fa/strings.xml b/packages/Shell/res/values-fa/strings.xml
index b619f10..591ef0d 100644
--- a/packages/Shell/res/values-fa/strings.xml
+++ b/packages/Shell/res/values-fa/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"عکس صفحه‌نمایش با موفقیت گرفته شد."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"نمی‌توان عکس صفحه‌نمایش گرفت."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"جزئیات گزارش اشکال"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"نام مخفف"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"خلاصه یک خطی"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"جزئیات دقیق"</string>
 </resources>
diff --git a/packages/Shell/res/values-fi/strings.xml b/packages/Shell/res/values-fi/strings.xml
index a90ffb5..766ff23 100644
--- a/packages/Shell/res/values-fi/strings.xml
+++ b/packages/Shell/res/values-fi/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Kuvakaappaus tallennettu."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Kuvakaappauksen tallentaminen epäonnistui."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Virheraportin tiedot"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Lyhyt nimi"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Lyhyt tiivistelmä"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Yksityiskohtainen kuvaus"</string>
 </resources>
diff --git a/packages/Shell/res/values-fr-rCA/strings.xml b/packages/Shell/res/values-fr-rCA/strings.xml
index 52be99d..8bff08f 100644
--- a/packages/Shell/res/values-fr-rCA/strings.xml
+++ b/packages/Shell/res/values-fr-rCA/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"La saisie d\'écran a réussi."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Une erreur s\'est produite lors de la saisie d\'écran."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Détails du rapport de bogue"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Nom abrégé"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Résumé d\'une ligne"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Description détaillée"</string>
 </resources>
diff --git a/packages/Shell/res/values-fr/strings.xml b/packages/Shell/res/values-fr/strings.xml
index e10e28e..4e5c3c1 100644
--- a/packages/Shell/res/values-fr/strings.xml
+++ b/packages/Shell/res/values-fr/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"La capture d\'écran a bien été effectuée."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Impossible d\'effectuer une capture d\'écran."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Détails du rapport de bug"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Nom court"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Résumé d\'une ligne"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Description détaillée"</string>
 </resources>
diff --git a/packages/Shell/res/values-gl-rES/strings.xml b/packages/Shell/res/values-gl-rES/strings.xml
index 20f8cda..099f92a 100644
--- a/packages/Shell/res/values-gl-rES/strings.xml
+++ b/packages/Shell/res/values-gl-rES/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"A captura de pantalla realizouse correctamente."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Non se puido realizar a captura de pantalla."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalles do informe de erros"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Nome abreviado"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Resumo de 1 liña"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Descrición detallada"</string>
 </resources>
diff --git a/packages/Shell/res/values-gu-rIN/strings.xml b/packages/Shell/res/values-gu-rIN/strings.xml
index 967d255..9943ffb 100644
--- a/packages/Shell/res/values-gu-rIN/strings.xml
+++ b/packages/Shell/res/values-gu-rIN/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"સ્ક્રીનશોટ સફળતાપૂર્વક લેવાયો."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"સ્ક્રીનશોટ લઇ શકાયો નથી."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"બગ રિપોર્ટની વિગતો"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"નાનું નામ"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"1-રેખાનો સારાંશ"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"વિગતવાર વર્ણન"</string>
 </resources>
diff --git a/packages/Shell/res/values-hi/strings.xml b/packages/Shell/res/values-hi/strings.xml
index 70e4f38..cf871b6 100644
--- a/packages/Shell/res/values-hi/strings.xml
+++ b/packages/Shell/res/values-hi/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"स्क्रीनशॉट सफलतापूर्वक लिया गया."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"स्क्रीनशॉट नहीं लिया जा सका."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"बग रिपोर्ट के विवरण"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"संक्षिप्त नाम"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"1-पंक्ति में सारांश"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"विस्तृत वर्णन"</string>
 </resources>
diff --git a/packages/Shell/res/values-hr/strings.xml b/packages/Shell/res/values-hr/strings.xml
index f38a281..5072b6b 100644
--- a/packages/Shell/res/values-hr/strings.xml
+++ b/packages/Shell/res/values-hr/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Zaslon je snimljen."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Snimanje zaslona nije uspjelo."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Pojedinosti izvješća o programskoj pogrešci"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Kratko ime"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Sažetak u jednom retku"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detaljan opis"</string>
 </resources>
diff --git a/packages/Shell/res/values-hu/strings.xml b/packages/Shell/res/values-hu/strings.xml
index 544c117..400cd18 100644
--- a/packages/Shell/res/values-hu/strings.xml
+++ b/packages/Shell/res/values-hu/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Sikerült elkészíteni a képernyőképet."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Nem sikerült elkészíteni a képernyőképet."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Hibajelentés részletei"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Rövid név"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Egysoros összefoglalás"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Részletes leírás"</string>
 </resources>
diff --git a/packages/Shell/res/values-hy-rAM/strings.xml b/packages/Shell/res/values-hy-rAM/strings.xml
index 625994d..2febc7d 100644
--- a/packages/Shell/res/values-hy-rAM/strings.xml
+++ b/packages/Shell/res/values-hy-rAM/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Էկրանի պատկերը հաջողությամբ ստացվեց:"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Չհաջողվեց ստանալ էկրանի պատկերը:"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Վրիպակի զեկույցի մանրամասները"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Կրճատ անուն"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Ամփոփագիր մեկ տողով"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Մանրամասն նկարագրություն"</string>
 </resources>
diff --git a/packages/Shell/res/values-in/strings.xml b/packages/Shell/res/values-in/strings.xml
index 747fecd..400cb98 100644
--- a/packages/Shell/res/values-in/strings.xml
+++ b/packages/Shell/res/values-in/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Tangkapan layar berhasil diambil."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Tangkapan layar tidak dapat diambil."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detail laporan bug"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Nama pendek"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Ringkasan 1 baris"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Deskripsi detail"</string>
 </resources>
diff --git a/packages/Shell/res/values-is-rIS/strings.xml b/packages/Shell/res/values-is-rIS/strings.xml
index d0d3e60..1886d6e 100644
--- a/packages/Shell/res/values-is-rIS/strings.xml
+++ b/packages/Shell/res/values-is-rIS/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Tókst að taka skjámynd."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Ekki tókst að taka skjámynd."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Upplýsingar um villutilkynningu"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Stutt heiti"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Einnar línu samantekt"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Ítarleg lýsing"</string>
 </resources>
diff --git a/packages/Shell/res/values-it/strings.xml b/packages/Shell/res/values-it/strings.xml
index 0511c58..39532dc 100644
--- a/packages/Shell/res/values-it/strings.xml
+++ b/packages/Shell/res/values-it/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Screenshot acquisito."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Impossibile acquisire lo screenshot."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Dettagli della segnalazione di bug"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Nome breve"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Sintesi su una riga"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Descrizione dettagliata"</string>
 </resources>
diff --git a/packages/Shell/res/values-iw/strings.xml b/packages/Shell/res/values-iw/strings.xml
index b9bcaf9..c950b49 100644
--- a/packages/Shell/res/values-iw/strings.xml
+++ b/packages/Shell/res/values-iw/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"צילום המסך בוצע בהצלחה."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"לא ניתן היה לצלם מסך."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"פרטי דוח על באג"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"כינוי"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"סיכום בשורה אחת"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"תיאור מפורט"</string>
 </resources>
diff --git a/packages/Shell/res/values-ja/strings.xml b/packages/Shell/res/values-ja/strings.xml
index 05b95eb..5fb0abf 100644
--- a/packages/Shell/res/values-ja/strings.xml
+++ b/packages/Shell/res/values-ja/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"スクリーンショットを撮影しました。"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"スクリーンショットを撮影できませんでした。"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"バグレポートの詳細"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"省略名"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"1 行の概要"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"詳細説明"</string>
 </resources>
diff --git a/packages/Shell/res/values-ka-rGE/strings.xml b/packages/Shell/res/values-ka-rGE/strings.xml
index 2cfd80a..34aa416 100644
--- a/packages/Shell/res/values-ka-rGE/strings.xml
+++ b/packages/Shell/res/values-ka-rGE/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"ეკრანის ანაბეჭდი გადაღებულია წარმატებით."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ეკრანის ანაბეჭდის გადაღება ვერ მოხერხდა."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ხარვეზის შესახებ ანგარიშის დეტალები"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"მოკლე სახელი"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"1-ხაზიანი რეზიუმე"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"დეტალური აღწერა"</string>
 </resources>
diff --git a/packages/Shell/res/values-kk-rKZ/strings.xml b/packages/Shell/res/values-kk-rKZ/strings.xml
index 2829b9b..a736dd8 100644
--- a/packages/Shell/res/values-kk-rKZ/strings.xml
+++ b/packages/Shell/res/values-kk-rKZ/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Скриншот сәтті түсірілді."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Скриншот түсіру мүмкін болмады."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Қате туралы есептің мәліметтері"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Қысқа аты"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"1 жолдық жиынтық мәліметтер"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Егжей-тегжейлі сипаттама"</string>
 </resources>
diff --git a/packages/Shell/res/values-km-rKH/strings.xml b/packages/Shell/res/values-km-rKH/strings.xml
index 3573588..128f6e0 100644
--- a/packages/Shell/res/values-km-rKH/strings.xml
+++ b/packages/Shell/res/values-km-rKH/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"បានថតរូបថតអេក្រង់ដោយជោគជ័យ"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"មិនអាចថតរូបថតអេក្រង់បានទេ"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ព័ត៌មានលម្អិតពីរបាយការណ៍កំហុស"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"ឈ្មោះ​ខ្លី"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"ការសង្ខេបមួយជួរ"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"ការពិពណ៌នាលម្អិត"</string>
 </resources>
diff --git a/packages/Shell/res/values-kn-rIN/strings.xml b/packages/Shell/res/values-kn-rIN/strings.xml
index 7071264..876e1b4 100644
--- a/packages/Shell/res/values-kn-rIN/strings.xml
+++ b/packages/Shell/res/values-kn-rIN/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ ಯಶಸ್ವಿಯಾಗಿ ತೆಗೆದುಕೊಳ್ಳಲಾಗಿದೆ."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ ತೆಗೆದುಕೊಳ್ಳಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ಬಗ್ ವರದಿ ವಿವರಗಳು"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"ಚಿಕ್ಕ ಹೆಸರು"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"1-ಸಾಲಿನ ಸಾರಾಂಶ"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"ವಿವರವಾದ ವಿವರಣೆ"</string>
 </resources>
diff --git a/packages/Shell/res/values-ko/strings.xml b/packages/Shell/res/values-ko/strings.xml
index 4e3c3f4..80dc6bb 100644
--- a/packages/Shell/res/values-ko/strings.xml
+++ b/packages/Shell/res/values-ko/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"스크린샷을 찍었습니다."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"스크린샷을 찍을 수 없습니다."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"버그 신고 세부정보"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"짧은 이름"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"한 줄 요약"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"자세한 설명"</string>
 </resources>
diff --git a/packages/Shell/res/values-ky-rKG/strings.xml b/packages/Shell/res/values-ky-rKG/strings.xml
index 051be38..00be46b 100644
--- a/packages/Shell/res/values-ky-rKG/strings.xml
+++ b/packages/Shell/res/values-ky-rKG/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Скриншот ийгиликтүү тартылды."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Скриншот тартылбай койду."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Мүчүлүштүктөр жөнүндө кабардын чоо-жайы"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Кыска аталышы"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"1 саптык корутунду"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Кененирээк маалымат"</string>
 </resources>
diff --git a/packages/Shell/res/values-lo-rLA/strings.xml b/packages/Shell/res/values-lo-rLA/strings.xml
index a04a355..58b3daf 100644
--- a/packages/Shell/res/values-lo-rLA/strings.xml
+++ b/packages/Shell/res/values-lo-rLA/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"ຖ່າຍພາບໜ້າຈໍສຳເລັດແລ້ວ."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ບໍ່ສາມາດຖ່າຍພາບໜ້າຈໍໄດ້."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ລາຍ​ລະ​ອຽດ​ການລາຍງານບັນຫາ"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"ຊື່ສັ້ນ"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"ສະຫຼຸບ 1 ແຖວ"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"ຄຳອະທິບາຍແບບລະອຽດ"</string>
 </resources>
diff --git a/packages/Shell/res/values-lt/strings.xml b/packages/Shell/res/values-lt/strings.xml
index 8d8d31e..9419ad3 100644
--- a/packages/Shell/res/values-lt/strings.xml
+++ b/packages/Shell/res/values-lt/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Ekrano kopija sėkmingai padaryta."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Nepavyko padaryti ekrano kopijos."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Išsami pranešimo apie riktą informacija"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Trumpasis pavadinimas"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"1 eilutės suvestinė"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Išsamus aprašas"</string>
 </resources>
diff --git a/packages/Shell/res/values-lv/strings.xml b/packages/Shell/res/values-lv/strings.xml
index dba1ad3..574fd0b 100644
--- a/packages/Shell/res/values-lv/strings.xml
+++ b/packages/Shell/res/values-lv/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Ekrānuzņēmums ir veikts sekmīgi."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Nevarēja veikt ekrānuzņēmumu."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Kļūdas pārskata informācija"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Saīsināts nosaukums"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Kopsavilkums 1 rindiņā"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detalizēts apraksts"</string>
 </resources>
diff --git a/packages/Shell/res/values-mk-rMK/strings.xml b/packages/Shell/res/values-mk-rMK/strings.xml
index 6e23ad8..dc1f249 100644
--- a/packages/Shell/res/values-mk-rMK/strings.xml
+++ b/packages/Shell/res/values-mk-rMK/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Успешно е направена слика од екранот."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Не може да се направи слика од екранот."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Детали на извештајот за грешка"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Кратко име"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Резиме во 1 ред"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Детален опис"</string>
 </resources>
diff --git a/packages/Shell/res/values-ml-rIN/strings.xml b/packages/Shell/res/values-ml-rIN/strings.xml
index 73a4fff..7f411a4 100644
--- a/packages/Shell/res/values-ml-rIN/strings.xml
+++ b/packages/Shell/res/values-ml-rIN/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"സ്ക്രീൻഷോട്ട് എടുത്തു."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"സ്ക്രീൻഷോട്ട് എടുക്കാൻ കഴിഞ്ഞില്ല."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ബഗ് റിപ്പോർട്ട് വിശദാംശങ്ങൾ"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"ഹ്രസ്വ നാമം"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"ഒരു വരി സംഗ്രഹം"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"വിശദമായ വിവരണം"</string>
 </resources>
diff --git a/packages/Shell/res/values-mn-rMN/strings.xml b/packages/Shell/res/values-mn-rMN/strings.xml
index 1f4be4a..1f47fbf 100644
--- a/packages/Shell/res/values-mn-rMN/strings.xml
+++ b/packages/Shell/res/values-mn-rMN/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Дэлгэцийн зургийг амжилттай авлаа."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Дэлгэцийн зураг авах боломжгүй."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Алдааны дэлгэрэнгүй тайлан"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Богино нэр"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"1-р шугамын хураангуй"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Дэлгэрэнгүй тайлбар"</string>
 </resources>
diff --git a/packages/Shell/res/values-mr-rIN/strings.xml b/packages/Shell/res/values-mr-rIN/strings.xml
index 6b06cf5..89c9275 100644
--- a/packages/Shell/res/values-mr-rIN/strings.xml
+++ b/packages/Shell/res/values-mr-rIN/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"स्क्रीनशॉट यशस्वीपणे घेतला."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"स्क्रीनशॉट घेणे शक्य झाले नाही."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"दोष अहवाल तपशील"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"लघु नाव"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"1-ओळीचा सारांश"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"तपशीलवार वर्णन"</string>
 </resources>
diff --git a/packages/Shell/res/values-ms-rMY/strings.xml b/packages/Shell/res/values-ms-rMY/strings.xml
index e22f880..c588a05 100644
--- a/packages/Shell/res/values-ms-rMY/strings.xml
+++ b/packages/Shell/res/values-ms-rMY/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Tangkapan skrin berjaya diambil."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Tangkapan skrin tidak dapat diambil."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Butiran laporan pepijat"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Nama pendek"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Ringkasan 1 baris"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Perihalan terperinci"</string>
 </resources>
diff --git a/packages/Shell/res/values-my-rMM/strings.xml b/packages/Shell/res/values-my-rMM/strings.xml
index 727cdc9..728eb98 100644
--- a/packages/Shell/res/values-my-rMM/strings.xml
+++ b/packages/Shell/res/values-my-rMM/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"မျက်နှာပြင် လျှပ်တစ်ပြက်ပုံကို အောင်မြင်စွာ ရိုက်ပြီးပြီ။"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"မျက်နှာပြင် လျှပ်တစ်ပြက်ပုံ မရိုက်နိုင်ပါ"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ချွတ်ယွင်းချက်အစီရင်ခံစာ အသေးစိတ်များ"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"အမည်အတိုကောက်"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"လိုင်း ၁ လိုင်းအကျဉ်းချုပ်"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"အသေးစိတ် ဖော်ပြချက်"</string>
 </resources>
diff --git a/packages/Shell/res/values-nb/strings.xml b/packages/Shell/res/values-nb/strings.xml
index c7702ef..dff2a83 100644
--- a/packages/Shell/res/values-nb/strings.xml
+++ b/packages/Shell/res/values-nb/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Skjermdumpen er tatt."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Skjermdumpen kunne ikke tas."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detaljer om feilrapporten"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Kallenavn"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Sammendrag på én linje"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detaljert beskrivelse"</string>
 </resources>
diff --git a/packages/Shell/res/values-ne-rNP/strings.xml b/packages/Shell/res/values-ne-rNP/strings.xml
index 732f398..ec87f35 100644
--- a/packages/Shell/res/values-ne-rNP/strings.xml
+++ b/packages/Shell/res/values-ne-rNP/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"स्क्रिनशट सफलतापूर्वक लिइयो।"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"स्क्रिनशट लिन सकिएन।"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"बग रिपोर्टको विवरण"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"छोटो नाम"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"१ लाइनको सारांश"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"विस्तृत विवरण"</string>
 </resources>
diff --git a/packages/Shell/res/values-nl/strings.xml b/packages/Shell/res/values-nl/strings.xml
index 0378ca4..b700af5 100644
--- a/packages/Shell/res/values-nl/strings.xml
+++ b/packages/Shell/res/values-nl/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Screenshot is gemaakt."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Screenshot kan niet worden gemaakt."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Details van bugrapport"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Korte naam"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Samenvatting van één regel"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Gedetailleerde beschrijving"</string>
 </resources>
diff --git a/packages/Shell/res/values-pa-rIN/strings.xml b/packages/Shell/res/values-pa-rIN/strings.xml
index 720bde0..15833be 100644
--- a/packages/Shell/res/values-pa-rIN/strings.xml
+++ b/packages/Shell/res/values-pa-rIN/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਸਫਲਤਾਪੂਰਵਕ ਲਿਆ ਗਿਆ।"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਨਹੀਂ ਲਿਆ ਜਾ ਸਕਿਆ।"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ਬੱਗ ਰਿਪੋਰਟ ਵੇਰਵੇ"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"ਛੋਟਾ ਨਾਮ"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"1-ਲਾਈਨ ਸਾਰਾਂਸ਼"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"ਵਿਸਥਾਰ ਸਹਿਤ ਵਰਣਨ"</string>
 </resources>
diff --git a/packages/Shell/res/values-pl/strings.xml b/packages/Shell/res/values-pl/strings.xml
index d6715a5..9985a91 100644
--- a/packages/Shell/res/values-pl/strings.xml
+++ b/packages/Shell/res/values-pl/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Zrobiono zrzut ekranu."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Nie udało się zrobić zrzutu ekranu."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Szczegóły zgłoszenia błędu"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Krótka nazwa"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Jednowierszowe podsumowanie"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Szczegółowy opis"</string>
 </resources>
diff --git a/packages/Shell/res/values-pt-rBR/strings.xml b/packages/Shell/res/values-pt-rBR/strings.xml
index fb16dd8..745efb3 100644
--- a/packages/Shell/res/values-pt-rBR/strings.xml
+++ b/packages/Shell/res/values-pt-rBR/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Captura de tela concluída."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Não foi possível fazer a captura de tela."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalhes do relatório do bug"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Apelido"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Resumo de uma linha"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Descrição detalhada"</string>
 </resources>
diff --git a/packages/Shell/res/values-pt-rPT/strings.xml b/packages/Shell/res/values-pt-rPT/strings.xml
index 07d319e..9252068 100644
--- a/packages/Shell/res/values-pt-rPT/strings.xml
+++ b/packages/Shell/res/values-pt-rPT/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Captura de ecrã tirada com êxito."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Não foi possível tirar a captura de ecrã."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalhes do relatório de erro"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Nome abreviado"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Resumo de 1 linha"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Descrição detalhada"</string>
 </resources>
diff --git a/packages/Shell/res/values-pt/strings.xml b/packages/Shell/res/values-pt/strings.xml
index fb16dd8..745efb3 100644
--- a/packages/Shell/res/values-pt/strings.xml
+++ b/packages/Shell/res/values-pt/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Captura de tela concluída."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Não foi possível fazer a captura de tela."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalhes do relatório do bug"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Apelido"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Resumo de uma linha"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Descrição detalhada"</string>
 </resources>
diff --git a/packages/Shell/res/values-ro/strings.xml b/packages/Shell/res/values-ro/strings.xml
index 064dfaf..77a6cfd 100644
--- a/packages/Shell/res/values-ro/strings.xml
+++ b/packages/Shell/res/values-ro/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Captura de ecran a fost făcută."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Captura de ecran nu a putut fi făcută."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalii privind raportul de eroare"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Nume scurt"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Rezumat de un rând"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Descriere detaliată"</string>
 </resources>
diff --git a/packages/Shell/res/values-ru/strings.xml b/packages/Shell/res/values-ru/strings.xml
index 3350740..18502cf 100644
--- a/packages/Shell/res/values-ru/strings.xml
+++ b/packages/Shell/res/values-ru/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Скриншот готов"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Не удалось сделать скриншот"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Детали отчета об ошибке"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Краткое название"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Краткое описание ошибки"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Подробное описание"</string>
 </resources>
diff --git a/packages/Shell/res/values-si-rLK/strings.xml b/packages/Shell/res/values-si-rLK/strings.xml
index d915109..25bef76 100644
--- a/packages/Shell/res/values-si-rLK/strings.xml
+++ b/packages/Shell/res/values-si-rLK/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"සාර්ථකව තිර රුවක් ගන්නා ලදී."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"තිර රුවක් ගත නොහැකි විය."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"දෝෂ වාර්තා විස්තර"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"කෙටි නම"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"පේළි-1 සාරාංශය"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"සවිස්තර විස්තරය"</string>
 </resources>
diff --git a/packages/Shell/res/values-sk/strings.xml b/packages/Shell/res/values-sk/strings.xml
index ec9003d..d874169 100644
--- a/packages/Shell/res/values-sk/strings.xml
+++ b/packages/Shell/res/values-sk/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Snímka obrazovky bola zaznamenaná."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Snímku obrazovky sa nepodarilo zaznamenať."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Podrobnosti hlásenia chyby"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Skrátený názov"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Jednoriadkové zhrnutie"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Podrobný popis"</string>
 </resources>
diff --git a/packages/Shell/res/values-sl/strings.xml b/packages/Shell/res/values-sl/strings.xml
index aa66ce9..f7ccc4b 100644
--- a/packages/Shell/res/values-sl/strings.xml
+++ b/packages/Shell/res/values-sl/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Posnetek zaslon je bil uspešno ustvarjen."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Posnetka zaslon ni bilo mogoče ustvariti."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Podrobnosti o poročilu o napakah"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Ime"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Enovrstični povzetek"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Podroben opis"</string>
 </resources>
diff --git a/packages/Shell/res/values-sq-rAL/strings.xml b/packages/Shell/res/values-sq-rAL/strings.xml
index dd13f34..529caf8 100644
--- a/packages/Shell/res/values-sq-rAL/strings.xml
+++ b/packages/Shell/res/values-sq-rAL/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Pamja e ekranit u realizua me sukses."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Pamja e ekranit nuk mund të realizohej."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detajet e raportimit të gabimeve në kod"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Emri shkurt"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Përmbledhje me 1 rresht"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Përshkrimi i detajuar"</string>
 </resources>
diff --git a/packages/Shell/res/values-sr/strings.xml b/packages/Shell/res/values-sr/strings.xml
index 1da7ecb..740d2fb 100644
--- a/packages/Shell/res/values-sr/strings.xml
+++ b/packages/Shell/res/values-sr/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Снимање екрана је успело."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Снимање екрана није успело."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Детаљи извештаја о грешци"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Кратки назив"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Резиме у једном реду"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Детаљни опис"</string>
 </resources>
diff --git a/packages/Shell/res/values-sv/strings.xml b/packages/Shell/res/values-sv/strings.xml
index 8afa0a5..1df2110 100644
--- a/packages/Shell/res/values-sv/strings.xml
+++ b/packages/Shell/res/values-sv/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"En skärmdump har tagits."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Det gick inte att ta skrämdump."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Information för felrapporten"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Kortnamn"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Sammanfattning på en rad"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detaljerad beskrivning"</string>
 </resources>
diff --git a/packages/Shell/res/values-sw/strings.xml b/packages/Shell/res/values-sw/strings.xml
index 5b70262..bb7364d 100644
--- a/packages/Shell/res/values-sw/strings.xml
+++ b/packages/Shell/res/values-sw/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Imepiga picha ya skrini."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Haikupiga picha ya skrini."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Maelezo kuhusu ripoti ya hitilafu"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Jina fupi"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Muhtasari wa mstari mmoja"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Maelezo ya kina"</string>
 </resources>
diff --git a/packages/Shell/res/values-ta-rIN/strings.xml b/packages/Shell/res/values-ta-rIN/strings.xml
index 91eb718..28e884f 100644
--- a/packages/Shell/res/values-ta-rIN/strings.xml
+++ b/packages/Shell/res/values-ta-rIN/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"ஸ்கிரீன் ஷாட் எடுக்கப்பட்டது."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ஸ்கிரீன் ஷாட்டை எடுக்க முடியவில்லை."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"பிழை அறிக்கை விவரங்கள்"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"சுருக்கப் பெயர்"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"சுருக்கவிவரம் (ஒரு வரியில்)"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"விரிவான விளக்கம்"</string>
 </resources>
diff --git a/packages/Shell/res/values-te-rIN/strings.xml b/packages/Shell/res/values-te-rIN/strings.xml
index 517dd5e..71e3838 100644
--- a/packages/Shell/res/values-te-rIN/strings.xml
+++ b/packages/Shell/res/values-te-rIN/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"స్క్రీన్‌షాట్ విజయవంతంగా తీయబడింది."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"స్క్రీన్‌షాట్‌ను తీయడం సాధ్యపడలేదు."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"బగ్ నివేదిక వివరాలు"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"చిన్న పేరు"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"1-పంక్తి సారాంశం"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"సమగ్ర వివరణ"</string>
 </resources>
diff --git a/packages/Shell/res/values-th/strings.xml b/packages/Shell/res/values-th/strings.xml
index b734095..fd2749d 100644
--- a/packages/Shell/res/values-th/strings.xml
+++ b/packages/Shell/res/values-th/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"จับภาพหน้าจอสำเร็จแล้ว"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ไม่สามารถจับภาพหน้าจอได้"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"รายละเอียดรายงานข้อบกพร่อง"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"ชื่อย่อ"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"สรุป 1 บรรทัด"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"คำอธิบายโดยละเอียด"</string>
 </resources>
diff --git a/packages/Shell/res/values-tl/strings.xml b/packages/Shell/res/values-tl/strings.xml
index bcce1db..3301113 100644
--- a/packages/Shell/res/values-tl/strings.xml
+++ b/packages/Shell/res/values-tl/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Nakunan ng screenshot."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Hindi makunan ng screenshot."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Mga detalye ng ulat ng bug"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Maikling pangalan"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Buod na may 1 linya"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detalyadong paglalarawan"</string>
 </resources>
diff --git a/packages/Shell/res/values-tr/strings.xml b/packages/Shell/res/values-tr/strings.xml
index e1fdf10..746458d 100644
--- a/packages/Shell/res/values-tr/strings.xml
+++ b/packages/Shell/res/values-tr/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Ekran görüntüsü başarıyla alındı."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Ekran görüntüsü alınamadı."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Hata raporu ayrıntıları"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Kısa ad"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"1 satırlık özet"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Ayrıntılı açıklama"</string>
 </resources>
diff --git a/packages/Shell/res/values-uk/strings.xml b/packages/Shell/res/values-uk/strings.xml
index dd43c4c..1f6210e 100644
--- a/packages/Shell/res/values-uk/strings.xml
+++ b/packages/Shell/res/values-uk/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Знімок екрана зроблено."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Не вдалося зробити знімок екрана."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Деталі повідомлення про помилку"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Коротка назва"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Підсумок одним рядком"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Детальний опис"</string>
 </resources>
diff --git a/packages/Shell/res/values-ur-rPK/strings.xml b/packages/Shell/res/values-ur-rPK/strings.xml
index b97c8b5..1f09245 100644
--- a/packages/Shell/res/values-ur-rPK/strings.xml
+++ b/packages/Shell/res/values-ur-rPK/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"اسکرین شاٹ کامیابی سے لے لیا گیا۔"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"سکرین شاٹ نہیں لیا جا سکا۔"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"بگ رپورٹ کی تفصیلات"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"مختصر نام"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"1 لائن کا خلاصہ"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"تفصیلی وضاحت"</string>
 </resources>
diff --git a/packages/Shell/res/values-uz-rUZ/strings.xml b/packages/Shell/res/values-uz-rUZ/strings.xml
index 279c876..1cf320a 100644
--- a/packages/Shell/res/values-uz-rUZ/strings.xml
+++ b/packages/Shell/res/values-uz-rUZ/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Skrinshot tayyor."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Skrinshot olib bo‘lmadi."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Xatoliklar hisoboti tafsilotlari"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Qisqa nomi"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Xatolikning qisqacha ta’rifi"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Batafsil ta’rif"</string>
 </resources>
diff --git a/packages/Shell/res/values-vi/strings.xml b/packages/Shell/res/values-vi/strings.xml
index 4e1ebc7..4d7a89f 100644
--- a/packages/Shell/res/values-vi/strings.xml
+++ b/packages/Shell/res/values-vi/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Đã chụp ảnh màn hình thành công."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Không thể chụp ảnh màn hình."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Chi tiết báo cáo lỗi"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Tên ngắn"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Tóm tắt 1 dòng"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Mô tả chi tiết"</string>
 </resources>
diff --git a/packages/Shell/res/values-zh-rCN/strings.xml b/packages/Shell/res/values-zh-rCN/strings.xml
index b5ba7a9..ec418b3 100644
--- a/packages/Shell/res/values-zh-rCN/strings.xml
+++ b/packages/Shell/res/values-zh-rCN/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"已成功截图。"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"无法截图。"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"错误报告详细信息"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"简称"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"简短摘要(1 行)"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"详细说明"</string>
 </resources>
diff --git a/packages/Shell/res/values-zh-rHK/strings.xml b/packages/Shell/res/values-zh-rHK/strings.xml
index 896a920..7539755 100644
--- a/packages/Shell/res/values-zh-rHK/strings.xml
+++ b/packages/Shell/res/values-zh-rHK/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"成功拍攝螢幕擷取畫面。"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"無法擷取螢幕畫面。"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"錯誤報告詳情"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"簡稱"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"簡短摘要 (1 行)"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"詳細說明"</string>
 </resources>
diff --git a/packages/Shell/res/values-zh-rTW/strings.xml b/packages/Shell/res/values-zh-rTW/strings.xml
index 2bdf561..6c2834f 100644
--- a/packages/Shell/res/values-zh-rTW/strings.xml
+++ b/packages/Shell/res/values-zh-rTW/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"已成功拍攝螢幕擷取畫面。"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"無法拍攝螢幕擷取畫面。"</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"錯誤報告詳細資料"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"簡稱"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"簡短摘要"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"詳細說明"</string>
 </resources>
diff --git a/packages/Shell/res/values-zu/strings.xml b/packages/Shell/res/values-zu/strings.xml
index 652105a..60592b5 100644
--- a/packages/Shell/res/values-zu/strings.xml
+++ b/packages/Shell/res/values-zu/strings.xml
@@ -31,7 +31,9 @@
     <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Isithombe-skrini sithathwe ngempumelelo."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Isithombe-skrini asikwazanga ukuthathwa."</string>
     <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Imininingwane yombiko wesiphazamisi"</string>
-    <string name="bugreport_info_name" msgid="5089191832271852826">"Igama elifishane"</string>
-    <string name="bugreport_info_title" msgid="127167853370557175">"Isifinyezo somugqa ongu-1"</string>
+    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
+    <skip />
+    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
+    <skip />
     <string name="bugreport_info_description" msgid="4117088998733546784">"Incazelo enemininingwane"</string>
 </resources>
diff --git a/packages/Shell/res/values/strings.xml b/packages/Shell/res/values/strings.xml
index dcd5f04..1459d53 100644
--- a/packages/Shell/res/values/strings.xml
+++ b/packages/Shell/res/values/strings.xml
@@ -58,10 +58,10 @@
 
     <!-- Text of the hint asking for the bug report name, which when set will define a suffix in the
          bug report file names. [CHAR LIMIT=30] -->
-    <string name="bugreport_info_name">Short name</string>
+    <string name="bugreport_info_name">Filename</string>
     <!-- Text of hint asking for the bug report title, which when set will define the
          Subject of the email message. [CHAR LIMIT=60] -->
-    <string name="bugreport_info_title">1-line summary</string>
+    <string name="bugreport_info_title">Title</string>
     <!-- Text of hint asking for the bug report description, which when set will describe
          what the bug report is about. [CHAR LIMIT=NONE] -->
     <string name="bugreport_info_description">Detailed description</string>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 8d57b88..c1f97a8 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -149,6 +149,12 @@
     <!-- DevicePolicyManager get user restrictions -->
     <uses-permission android:name="android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS" />
 
+    <!-- Needed for passing extras with intent ACTION_SHOW_ADMIN_SUPPORT_DETAILS -->
+    <uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
+
+    <!-- TV picture-in-picture -->
+    <uses-permission android:name="android.permission.RECEIVE_MEDIA_RESOURCE_USAGE" />
+
     <application
         android:name=".SystemUIApplication"
         android:persistent="true"
diff --git a/packages/SystemUI/res/drawable/ic_headset.xml b/packages/SystemUI/res/drawable/ic_headset.xml
new file mode 100644
index 0000000..58759f9
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_headset.xml
@@ -0,0 +1,28 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:insetLeft="2.5dp"
+    android:insetRight="2.5dp">
+    <vector
+        android:width="17.0dp"
+        android:height="17.0dp"
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0">
+        <path
+            android:fillColor="#FFFFFFFF"
+            android:pathData="M24.0,2.0C14.06,2.0 6.0,10.06 6.0,20.0l0.0,14.0c0.0,3.31 2.69,6.0 6.0,6.0l6.0,0.0L18.0,24.0l-8.0,0.0l0.0,-4.0c0.0,-7.73 6.27,-14.0 14.0,-14.0s14.0,6.27 14.0,14.0l0.0,4.0l-8.0,0.0l0.0,16.0l6.0,0.0c3.31,0.0 6.0,-2.69 6.0,-6.0L42.0,20.0c0.0,-9.94 -8.06,-18.0 -18.0,-18.0z"/>
+    </vector>
+</inset>
diff --git a/packages/SystemUI/res/drawable/ic_headset_mic.xml b/packages/SystemUI/res/drawable/ic_headset_mic.xml
new file mode 100644
index 0000000..5d02120
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_headset_mic.xml
@@ -0,0 +1,28 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:insetLeft="2.5dp"
+    android:insetRight="2.5dp">
+    <vector
+        android:width="17.0dp"
+        android:height="17.0dp"
+        android:viewportWidth="48.0"
+        android:viewportHeight="48.0">
+        <path
+            android:fillColor="#FFFFFFFF"
+            android:pathData="M24.0,2.0C14.06,2.0 6.0,10.06 6.0,20.0l0.0,14.0c0.0,3.31 2.69,6.0 6.0,6.0l6.0,0.0L18.0,24.0l-8.0,0.0l0.0,-4.0c0.0,-7.73 6.27,-14.0 14.0,-14.0s14.0,6.27 14.0,14.0l0.0,4.0l-8.0,0.0l0.0,16.0l8.0,0.0l0.0,2.0L24.0,42.0l0.0,4.0l12.0,0.0c3.31,0.0 6.0,-2.69 6.0,-6.0L42.0,20.0c0.0,-9.94 -8.06,-18.0 -18.0,-18.0z"/>
+    </vector>
+</inset>
diff --git a/packages/SystemUI/res/drawable/recents_info_dark.xml b/packages/SystemUI/res/drawable/recents_info_dark.xml
new file mode 100644
index 0000000..b1a2242
--- /dev/null
+++ b/packages/SystemUI/res/drawable/recents_info_dark.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="48.0dp"
+        android:height="48.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="@color/recents_task_bar_dark_icon_color"
+        android:pathData="M12.000000,2.000000C6.500000,2.000000 2.000000,6.500000 2.000000,12.000000s4.500000,10.000000 10.000000,10.000000c5.500000,0.000000 10.000000,-4.500000 10.000000,-10.000000S17.500000,2.000000 12.000000,2.000000zM13.000000,17.000000l-2.000000,0.000000l0.000000,-6.000000l2.000000,0.000000L13.000000,17.000000zM13.000000,9.000000l-2.000000,0.000000L11.000000,7.000000l2.000000,0.000000L13.000000,9.000000z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/recents_info_light.xml b/packages/SystemUI/res/drawable/recents_info_light.xml
new file mode 100644
index 0000000..bc58c3b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/recents_info_light.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="48.0dp"
+        android:height="48.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:pathData="M12.000000,2.000000C6.500000,2.000000 2.000000,6.500000 2.000000,12.000000s4.500000,10.000000 10.000000,10.000000c5.500000,0.000000 10.000000,-4.500000 10.000000,-10.000000S17.500000,2.000000 12.000000,2.000000zM13.000000,17.000000l-2.000000,0.000000l0.000000,-6.000000l2.000000,0.000000L13.000000,17.000000zM13.000000,9.000000l-2.000000,0.000000L11.000000,7.000000l2.000000,0.000000L13.000000,9.000000z"
+        android:fillColor="#FFFFFF"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_auto_rotate_landscape.xml b/packages/SystemUI/res/drawable/stat_sys_auto_rotate_landscape.xml
new file mode 100644
index 0000000..ba0709e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_auto_rotate_landscape.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:insetLeft="2.5dp"
+    android:insetRight="2.5dp">
+    <vector
+        android:height="17dp"
+        android:width="17dp"
+        android:viewportHeight="48"
+        android:viewportWidth="48" >
+        <group
+            android:name="ic_screen_rotation_48px_outlines"
+            android:translateX="24"
+            android:translateY="24" >
+            <group
+                android:name="ic_screen_rotation_48px_outlines_pivot"
+                android:translateX="-24.15"
+                android:translateY="-24.25" >
+                <group
+                    android:name="arrows"
+                    android:translateX="24.1"
+                    android:translateY="24.1" >
+                    <group
+                        android:name="arrows_pivot"
+                        android:translateX="-24.1"
+                        android:translateY="-24.1" >
+                        <path
+                            android:name="arrow_top"
+                            android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
+                            android:fillColor="#FFFFFFFF"
+                            android:fillAlpha="1" />
+                        <path
+                            android:name="arrow_bottom"
+                            android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
+                            android:fillColor="#FFFFFFFF"
+                            android:fillAlpha="1" />
+                    </group>
+                </group>
+                <group
+                    android:name="device"
+                    android:translateX="24.14999"
+                    android:translateY="24.25" >
+                    <path
+                        android:name="body"
+                        android:pathData="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+                        android:fillColor="#FFFFFFFF"
+                        android:fillAlpha="1" />
+                </group>
+            </group>
+        </group>
+    </vector>
+</inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_auto_rotate_portrait.xml b/packages/SystemUI/res/drawable/stat_sys_auto_rotate_portrait.xml
new file mode 100644
index 0000000..46a1f35
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_auto_rotate_portrait.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:insetLeft="2.5dp"
+    android:insetRight="2.5dp">
+    <vector
+        android:height="17dp"
+        android:width="17dp"
+        android:viewportHeight="48"
+        android:viewportWidth="48" >
+        <group
+            android:name="icon"
+            android:translateX="24"
+            android:translateY="24" >
+            <group
+                android:name="icon_pivot"
+                android:translateX="-24.15"
+                android:translateY="-24.25" >
+                <group
+                    android:name="arrows"
+                    android:translateX="24.1"
+                    android:translateY="24.1" >
+                    <group
+                        android:name="arrows_pivot"
+                        android:translateX="-24.1"
+                        android:translateY="-24.1" >
+                        <path
+                            android:name="arrow_top"
+                            android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
+                            android:fillColor="#FFFFFFFF"
+                            android:fillAlpha="1" />
+                        <path
+                            android:name="arrow_bottom"
+                            android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
+                            android:fillColor="#FFFFFFFF"
+                            android:fillAlpha="1" />
+                    </group>
+                </group>
+                <group
+                    android:name="device"
+                    android:translateX="24.14999"
+                    android:translateY="24.25" >
+                    <path
+                        android:name="device_1"
+                        android:pathData="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
+                        android:fillColor="#FFFFFFFF"
+                        android:fillAlpha="1" />
+                </group>
+            </group>
+        </group>
+    </vector>
+</inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_rotate_landscape.xml b/packages/SystemUI/res/drawable/stat_sys_rotate_landscape.xml
new file mode 100644
index 0000000..58ed7e6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_rotate_landscape.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:insetLeft="2.5dp"
+    android:insetRight="2.5dp">
+    <vector
+        android:height="17dp"
+        android:width="17dp"
+        android:viewportHeight="48"
+        android:viewportWidth="48" >
+        <group
+            android:name="ic_screen_rotation_48px_outlines"
+            android:translateX="24"
+            android:translateY="24" >
+            <group
+                android:name="ic_screen_rotation_48px_outlines_pivot"
+                android:translateX="-24.15"
+                android:translateY="-24.25" >
+                <group
+                    android:name="arrows"
+                    android:translateX="24.1"
+                    android:translateY="24.1"
+                    android:scaleX="0.9"
+                    android:scaleY="0.9"
+                    android:rotation="-135" >
+                    <group
+                        android:name="arrows_pivot"
+                        android:translateX="-24.1"
+                        android:translateY="-24.1" >
+                        <path
+                            android:name="arrow_top"
+                            android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
+                            android:fillColor="#FFFFFFFF"
+                            android:fillAlpha="0" />
+                        <path
+                            android:name="arrow_bottom"
+                            android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
+                            android:fillColor="#FFFFFFFF"
+                            android:fillAlpha="0" />
+                    </group>
+                </group>
+                <group
+                    android:name="device"
+                    android:translateX="24.14999"
+                    android:translateY="24.25"
+                    android:rotation="-45" >
+                    <path
+                        android:name="body"
+                        android:pathData="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+                        android:fillColor="#FFFFFFFF"
+                        android:fillAlpha="1" />
+                </group>
+            </group>
+        </group>
+    </vector>
+</inset>
diff --git a/packages/SystemUI/res/drawable/stat_sys_rotate_portrait.xml b/packages/SystemUI/res/drawable/stat_sys_rotate_portrait.xml
new file mode 100644
index 0000000..b63ffe0
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_rotate_portrait.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:insetLeft="2.5dp"
+    android:insetRight="2.5dp">
+    <vector
+        android:height="17dp"
+        android:width="17dp"
+        android:viewportHeight="48"
+        android:viewportWidth="48" >
+        <group
+            android:name="icon"
+            android:translateX="24"
+            android:translateY="24" >
+            <group
+                android:name="icon_pivot"
+                android:translateX="-24.15"
+                android:translateY="-24.25" >
+                <group
+                    android:name="arrows"
+                    android:translateX="24.1"
+                    android:translateY="24.1"
+                    android:scaleX="0.9"
+                    android:scaleY="0.9"
+                    android:rotation="-221" >
+                    <group
+                        android:name="arrows_pivot"
+                        android:translateX="-24.1"
+                        android:translateY="-24.1" >
+                        <path
+                            android:name="arrow_top"
+                            android:pathData="M 33.1499938965,5.25 c 6.5,3.10000610352 11.1999969482,9.40000915527 11.8999938965,17.0 c 0.0,0.0 3.00001525879,0.0 3.00001525879,0.0 c -1.00001525879,-12.3000030518 -11.3000030518,-22.0 -23.9000091553,-22.0 c -0.399993896484,0.0 -0.899993896484,0.0 -1.30000305176,0.100006103516 c 0.0,0.0 7.60000610352,7.59999084473 7.60000610352,7.59999084473 c 0.0,0.0 2.69999694824,-2.69999694824 2.69999694824,-2.69999694824 Z"
+                            android:fillColor="#FFFFFFFF"
+                            android:fillAlpha="0" />
+                        <path
+                            android:name="arrow_bottom"
+                            android:pathData="M 15.1499938965,43.25 c -6.5,-3.09999084473 -11.1999969482,-9.5 -11.8999938965,-17.0 c 0.0,0.0 -3.0,0.0 -3.0,0.0 c 1.0,12.3000030518 11.299987793,22.0 23.8999938965,22.0 c 0.399993896484,0.0 0.899993896484,0.0 1.30000305176,-0.0999908447266 c 0.0,0.0 -7.60000610352,-7.60000610352 -7.60000610352,-7.60000610352 c 0.0,0.0 -2.69999694824,2.69999694824 -2.69999694824,2.69999694824 Z"
+                            android:fillColor="#FFFFFFFF"
+                            android:fillAlpha="0" />
+                    </group>
+                </group>
+                <group
+                    android:name="device"
+                    android:translateX="24.14999"
+                    android:translateY="24.25"
+                    android:rotation="-135" >
+                    <path
+                        android:name="device_1"
+                        android:pathData="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
+                        android:fillColor="#FFFFFFFF"
+                        android:fillAlpha="1" />
+                </group>
+            </group>
+        </group>
+    </vector>
+</inset>
diff --git a/packages/SystemUI/res/layout/fullscreen_user_pod.xml b/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
similarity index 84%
rename from packages/SystemUI/res/layout/fullscreen_user_pod.xml
rename to packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
index 12f0a80..b7e666f 100644
--- a/packages/SystemUI/res/layout/fullscreen_user_pod.xml
+++ b/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
@@ -26,13 +26,13 @@
     <ImageView android:id="@+id/user_avatar"
                android:padding="10dp"
                android:layout_gravity="center"
-               android:layout_width="160dp"
-               android:layout_height="160dp" />
+               android:layout_width="@dimen/car_fullscreen_user_pod_image_avatar_width"
+               android:layout_height="@dimen/car_fullscreen_user_pod_image_avatar_height" />
 
     <TextView android:id="@+id/user_name"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
-              android:textSize="@dimen/qs_detail_item_secondary_text_size"
+              android:textSize="@dimen/car_fullscreen_user_pod_text_size"
               android:textColor="@color/qs_user_detail_name"
               android:gravity="center_horizontal" />
 </LinearLayout>
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml b/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
new file mode 100644
index 0000000..b953ff2
--- /dev/null
+++ b/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
@@ -0,0 +1,51 @@
+<?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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+             android:fitsSystemWindows="true"
+             android:layout_width="match_parent"
+             android:layout_height="match_parent"
+             android:visibility="gone">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/car_lockscreen_disclaimer_title"
+            android:textSize="@dimen/car_lockscreen_disclaimer_title_size"
+            android:paddingStart="@dimen/car_lockscreen_disclaimer_title_padding_start"
+            android:paddingTop="@dimen/car_lockscreen_disclaimer_title_padding_top" />
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/car_lockscreen_disclaimer_text"
+            android:textSize="@dimen/car_lockscreen_disclaimer_text_size"
+            android:paddingStart="@dimen/car_lockscreen_disclaimer_text_padding_start"
+            android:paddingEnd="@dimen/car_lockscreen_disclaimer_text_padding_end"
+            android:paddingTop="@dimen/car_lockscreen_disclaimer_text_padding_top" />
+        <com.android.systemui.statusbar.UserGridView
+            android:id="@+id/user_grid"
+            android:layout_gravity="center"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingTop="@dimen/car_lockscreen_user_grid_view_padding_top"
+            android:stretchMode="columnWidth">
+        </com.android.systemui.statusbar.UserGridView>
+    </LinearLayout>
+</FrameLayout>
diff --git a/packages/SystemUI/res/layout/car_navigation_button.xml b/packages/SystemUI/res/layout/car_navigation_button.xml
index 87c8f04..479f18d 100644
--- a/packages/SystemUI/res/layout/car_navigation_button.xml
+++ b/packages/SystemUI/res/layout/car_navigation_button.xml
@@ -22,7 +22,7 @@
         android:layout_height="match_parent"
         android:layout_width="wrap_content"
         android:orientation="horizontal"
-        android:gravity="center">
+        android:background="?android:attr/selectableItemBackground">
     <com.android.keyguard.AlphaOptimizedImageButton
             android:id="@+id/car_nav_button_icon"
             android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/fullscreen_user_switcher.xml b/packages/SystemUI/res/layout/fullscreen_user_switcher.xml
deleted file mode 100644
index 46c1896..0000000
--- a/packages/SystemUI/res/layout/fullscreen_user_switcher.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-             android:fitsSystemWindows="true"
-             android:layout_width="match_parent"
-             android:layout_height="match_parent"
-             android:visibility="gone">
-    <com.android.systemui.statusbar.UserGridView
-        android:id="@+id/user_grid"
-        android:layout_gravity="center"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:paddingStart="10dp"
-        android:paddingEnd="10dp"
-        android:columnWidth="180dp"
-        android:verticalSpacing="10dp"
-        android:horizontalSpacing="10dp"
-        android:stretchMode="columnWidth"
-        android:gravity="center">
-    </com.android.systemui.statusbar.UserGridView>
-</FrameLayout>
diff --git a/packages/SystemUI/res/layout/keyguard_user_switcher_item.xml b/packages/SystemUI/res/layout/keyguard_user_switcher_item.xml
index 2e67376..c6e453a 100644
--- a/packages/SystemUI/res/layout/keyguard_user_switcher_item.xml
+++ b/packages/SystemUI/res/layout/keyguard_user_switcher_item.xml
@@ -43,4 +43,4 @@
             sysui:frameWidth="@dimen/keyguard_user_switcher_border_thickness"
             sysui:framePadding="6dp"
             sysui:activeFrameColor="@color/current_user_border_color" />
-</com.android.systemui.qs.tiles.UserDetailItemView>
\ No newline at end of file
+</com.android.systemui.qs.tiles.UserDetailItemView>
diff --git a/packages/SystemUI/res/layout/qs_customize_layout.xml b/packages/SystemUI/res/layout/qs_customize_layout.xml
index 91cf894..0b8e02f 100644
--- a/packages/SystemUI/res/layout/qs_customize_layout.xml
+++ b/packages/SystemUI/res/layout/qs_customize_layout.xml
@@ -21,14 +21,6 @@
     android:layout_height="wrap_content"
     android:orientation="vertical">
 
-    <com.android.systemui.qs.QuickTileLayout
-        android:id="@+id/quick_tile_layout"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/qs_quick_actions_height"
-        android:orientation="horizontal"
-        android:paddingStart="@dimen/qs_quick_actions_padding"
-        android:paddingEnd="@dimen/qs_quick_actions_padding" />
-
     <view
         class="com.android.systemui.qs.PagedTileLayout$TilePage"
         android:id="@+id/tile_page"
diff --git a/packages/SystemUI/res/layout/qs_paged_tile_layout.xml b/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
index 6c236ea..127bddd 100644
--- a/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
+++ b/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
@@ -20,29 +20,6 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content">
 
-    <view
-        class="com.android.systemui.qs.PagedTileLayout$FirstPage"
-        android:id="@+id/first_page"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical">
-
-        <com.android.systemui.qs.QuickTileLayout
-            android:id="@+id/quick_tile_layout"
-            android:layout_width="match_parent"
-            android:layout_height="@dimen/qs_quick_actions_height"
-            android:orientation="horizontal"
-            android:paddingLeft="@dimen/qs_quick_actions_padding"
-            android:paddingRight="@dimen/qs_quick_actions_padding" />
-
-        <view
-            class="com.android.systemui.qs.PagedTileLayout$TilePage"
-            android:id="@+id/tile_page"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content" />
-
-    </view>
-
     <com.android.systemui.qs.PageIndicator
         android:id="@+id/page_indicator"
         android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/recents_task_view_header.xml b/packages/SystemUI/res/layout/recents_task_view_header.xml
index 07ac39a..a94e781 100644
--- a/packages/SystemUI/res/layout/recents_task_view_header.xml
+++ b/packages/SystemUI/res/layout/recents_task_view_header.xml
@@ -64,12 +64,19 @@
         android:background="@drawable/recents_button_bg"
         android:visibility="invisible"
         android:src="@drawable/recents_dismiss_light" />
-    <ProgressBar
-        android:id="@+id/focus_timer_indicator"
-        style="?android:attr/progressBarStyleHorizontal"
-        android:layout_width="match_parent"
-        android:layout_height="5dp"
-        android:layout_gravity="bottom"
-        android:indeterminateOnly="false"
-        android:visibility="invisible" />
+
+    <!-- The progress indicator shows if auto-paging is enabled -->
+    <ViewStub android:id="@+id/focus_timer_indicator_stub"
+               android:inflatedId="@+id/focus_timer_indicator"
+               android:layout="@layout/recents_task_view_header_progress_bar"
+               android:layout_width="match_parent"
+               android:layout_height="5dp"
+               android:layout_gravity="bottom" />
+
+    <!-- The app overlay shows as the user long-presses on the app icon -->
+    <ViewStub android:id="@+id/app_overlay_stub"
+               android:inflatedId="@+id/app_overlay"
+               android:layout="@layout/recents_task_view_header_overlay"
+               android:layout_width="match_parent"
+               android:layout_height="match_parent" />
 </com.android.systemui.recents.views.TaskViewHeader>
diff --git a/packages/SystemUI/res/layout/recents_task_view_header_overlay.xml b/packages/SystemUI/res/layout/recents_task_view_header_overlay.xml
new file mode 100644
index 0000000..5cdde9e
--- /dev/null
+++ b/packages/SystemUI/res/layout/recents_task_view_header_overlay.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:visibility="gone">
+    <com.android.systemui.recents.views.FixedSizeImageView
+        android:id="@+id/app_icon"
+        android:contentDescription="@string/recents_app_info_button_label"
+        android:layout_width="@dimen/recents_task_view_application_icon_size"
+        android:layout_height="@dimen/recents_task_view_application_icon_size"
+        android:layout_marginStart="8dp"
+        android:layout_gravity="center_vertical|start"
+        android:padding="8dp" />
+    <TextView
+        android:id="@+id/app_title"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical|start"
+        android:layout_marginStart="64dp"
+        android:layout_marginEnd="112dp"
+        android:textSize="16sp"
+        android:textColor="#ffffffff"
+        android:text="@string/recents_empty_message"
+        android:fontFamily="sans-serif-medium"
+        android:singleLine="true"
+        android:maxLines="2"
+        android:ellipsize="marquee"
+        android:fadingEdge="horizontal" />
+    <com.android.systemui.recents.views.FixedSizeImageView
+        android:id="@+id/app_info"
+        android:layout_width="48dp"
+        android:layout_height="48dp"
+        android:layout_marginEnd="4dp"
+        android:layout_gravity="center_vertical|end"
+        android:padding="12dp"
+        android:background="@drawable/recents_button_bg"
+        android:src="@drawable/recents_info_light" />
+</FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/recents_task_view_header_progress_bar.xml b/packages/SystemUI/res/layout/recents_task_view_header_progress_bar.xml
new file mode 100644
index 0000000..e740458
--- /dev/null
+++ b/packages/SystemUI/res/layout/recents_task_view_header_progress_bar.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<ProgressBar
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    style="?android:attr/progressBarStyleHorizontal"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:indeterminateOnly="false"
+    android:visibility="gone" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 39da8d0..4c80b48 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -80,7 +80,7 @@
     </FrameLayout>
 
     <ViewStub android:id="@+id/fullscreen_user_switcher_stub"
-              android:layout="@layout/fullscreen_user_switcher"
+              android:layout="@layout/car_fullscreen_user_switcher"
               android:layout_width="match_parent"
               android:layout_height="match_parent"/>
 
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index eeff2ed..cb68c9d 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -331,6 +331,8 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Volkome\nstilte"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Net\nprioriteit"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Net\nwekkers"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Alles"</string>
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Alle\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Laai tans (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> tot vol)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Laai tans vinnig (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> tot vol)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Laai tans stadig (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> tot vol)"</string>
@@ -480,4 +482,9 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Tuis"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Onlangs"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Terug"</string>
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Wys \'moenie steur nie\' in volume"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Laat volledige beheer van \'moenie steur nie\' toe in die volumedialoog."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volume en Moenie steur nie"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Aktiveer \'moenie steur nie\' met volume af"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Verlaat \'moenie steur nie\' met volume op"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index e9cb018..4d44de7 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -331,6 +331,8 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"ሙሉ ለሙሉ\nጸጥታ"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ቅድሚያ ተሰጪ\nብቻ"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"ማንቂያዎች\nብቻ"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"ሁሉም"</string>
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"ሁሉም\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>
@@ -480,4 +482,9 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"መነሻ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"የቅርብ ጊዜዎቹ"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"ተመለስ"</string>
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"በድምጽ ውስጥ አትረብሽን አሳይ"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"በድምጽ ንግግር ውስጥ አትረብሽን ሙሉ ቁጥጥር ይፍቀዱ።"</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"ድምጽ እና አትረብሽ"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"ድምጽ ሲቀነስ አትረብሽ አስገባ"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"ድምጽ ሲጨመር አትረብሽን ትተህ ውጣ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings_tv.xml b/packages/SystemUI/res/values-am/strings_tv.xml
new file mode 100644
index 0000000..0184601
--- /dev/null
+++ b/packages/SystemUI/res/values-am/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"PIPን ዝጋ"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"ሙሉ ማያ ገጽ"</string>
+    <string name="pip_play" msgid="674145557658227044">"አጫውት"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"ለአፍታ አቁም"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"ይቅር"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"PIPን ለመቆጣጠር መነሻን ተጭነው ይያዙ"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index f94069f..f7128e4 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -335,6 +335,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"كتم الصوت\nتمامًا"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"الأولوية \nفقط"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"التنبيهات\nفقط"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"الكل"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -484,4 +487,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"الشاشة الرئيسية"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"الأحدث"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"رجوع"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml
index e629774..71ced7c 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Tam\nsakitlik"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Yalnız\nprioritet"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Yalnız\nalarmlar"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Bütün"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Qidalanır (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> dolana kimi)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Sürətli qidalanır (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> dolana kimi)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Ləng qidalanır (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> dolana kimi)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Əsas səhifə"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Sonuncular"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Geri"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 0a864ca..fd98abc 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -332,6 +332,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Potpuna\ntišina"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Samo\npriorit. prekidi"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Samo\nalarmi"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Sve"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Punjenje (pun je za <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Brzo se puni (napuniće se za <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Sporo se puni (napuniće se za <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -481,4 +484,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Početni"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedavni sadržaj"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Nazad"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
new file mode 100644
index 0000000..7d35b20
--- /dev/null
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Zatvori PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Ceo ekran"</string>
+    <string name="pip_play" msgid="674145557658227044">"Pusti"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Pauziraj"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Otkaži"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Zadržite taster za POČETNI EKRAN da biste kontrolisali PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index ebdd1f3..e8f7f23 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Пълна\nтишина"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Само\nс приоритет"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Само\nбудилници"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Всички"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Начало"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Скорошни"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Назад"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings_tv.xml b/packages/SystemUI/res/values-bg/strings_tv.xml
new file mode 100644
index 0000000..82c2d08
--- /dev/null
+++ b/packages/SystemUI/res/values-bg/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Затваряне на режима „Картина в картина“"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Цял екран"</string>
+    <string name="pip_play" msgid="674145557658227044">"Пускане"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Пауза"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Отказ"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Задръжте „HOME“, за да контролирате режима „Картина в картина“"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml
index 2c30a82..a49ab40 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"একদম\nনিরব"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"শুধুমাত্র\nঅগ্রাধিকার"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"শুধুমাত্র\nঅ্যালার্মগুলি"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"সমস্ত"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"হোম"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"সাম্প্রতিকগুলি"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"পিছনে"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings_tv.xml b/packages/SystemUI/res/values-bn-rBD/strings_tv.xml
new file mode 100644
index 0000000..15d0e82
--- /dev/null
+++ b/packages/SystemUI/res/values-bn-rBD/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"PIP বন্ধ করুন"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"পূর্ণ স্ক্রীন"</string>
+    <string name="pip_play" msgid="674145557658227044">"চালান"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"বিরাম দিন"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"বাতিল করুন"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"PIP নিয়ন্ত্রণ করতে HOME ধরে রাখুন"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 6a57b23..0fce766 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Silenci\ntotal"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Només\ninterr. prior."</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Només\nalarmes"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Totes"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Carregant (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> per completar la càrrega)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Càrrega ràpida (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> per completar-se)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Càrrega lenta (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> per completar-se)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Inici"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recents"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Enrere"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings_tv.xml b/packages/SystemUI/res/values-ca/strings_tv.xml
new file mode 100644
index 0000000..8daa867
--- /dev/null
+++ b/packages/SystemUI/res/values-ca/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Tanca PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Pantalla completa"</string>
+    <string name="pip_play" msgid="674145557658227044">"Reprodueix"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Posa en pausa"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Cancel·la"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Mantén premut el botó INICI per controlar PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 275514c..6fff76b 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -333,6 +333,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Úplné\nticho"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Pouze\nprioritní"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Pouze\nbudíky"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Vše"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Nabíjení (plně nabito za <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Rychlé nabíjení (plně nabito za <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Pomalé nabíjení (plně nabito za <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -482,4 +485,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Plocha"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Poslední"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Zpět"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings_tv.xml b/packages/SystemUI/res/values-cs/strings_tv.xml
new file mode 100644
index 0000000..8675c78
--- /dev/null
+++ b/packages/SystemUI/res/values-cs/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Ukončit PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Celá obrazovka"</string>
+    <string name="pip_play" msgid="674145557658227044">"Přehrát"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Pozastavit"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Zrušit"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Chcete-li funkci PIP ovládat, podržte tlačítko PLOCHA"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index d0b9f66..2941927 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Total\nstilhed"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Kun\nprioritet"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Kun\nalarmer"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Alle"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Oplader (fuldt opladet om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Hurtig opladning (fuldt opladet om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Langsom opladning (fuldt opladet om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Start"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Seneste"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Tilbage"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings_tv.xml b/packages/SystemUI/res/values-da/strings_tv.xml
new file mode 100644
index 0000000..a40e34c
--- /dev/null
+++ b/packages/SystemUI/res/values-da/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Luk PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Fuld skærm"</string>
+    <string name="pip_play" msgid="674145557658227044">"Afspil"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Pause"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Annuller"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Hold HOME-knappen nede for at styre PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 071cc41..9afa618 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -73,7 +73,7 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Screenshot aufgenommen"</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Zum Ansehen berühren"</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Screenshot konnte nicht aufgenommen werden."</string>
-    <string name="screenshot_failed_text" msgid="1260203058661337274">"Screenshot nicht möglich. Entweder zu wenig Speicher oder die App/Ihr Unternehmen lässt dies nicht zu."</string>
+    <string name="screenshot_failed_text" msgid="1260203058661337274">"Screenshot nicht möglich. Entweder zu wenig Speicher oder die App/dein Unternehmen lässt dies nicht zu."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB-Dateiübertragungsoptionen"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"Als Medienplayer (MTP) bereitstellen"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"Als Kamera (PTP) bereitstellen"</string>
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Laut-\nlos"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Nur\nwichtige"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Nur\nWecker"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Alle"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Wird aufgeladen (voll in <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Wird schnell aufgeladen (voll in <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Wird langsam aufgeladen (voll in <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -364,7 +367,7 @@
     <string name="battery_saver_notification_title" msgid="237918726750955859">"Energiesparmodus ist aktiviert"</string>
     <string name="battery_saver_notification_text" msgid="820318788126672692">"Reduzierung der Leistung und Hintergrunddaten"</string>
     <string name="battery_saver_notification_action_text" msgid="109158658238110382">"Energiesparmodus deaktivieren"</string>
-    <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> nimmt alle auf Ihrem Bildschirm angezeigten Aktivitäten auf."</string>
+    <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> nimmt alle auf deinem Bildschirm angezeigten Aktivitäten auf."</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Nicht erneut anzeigen"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Alle löschen"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Jetzt starten"</string>
@@ -439,7 +442,7 @@
     <string name="tuner_toast" msgid="603429811084428439">"Herzlichen Glückwunsch! System UI Tuner wurde \"Einstellungen\" hinzugefügt."</string>
     <string name="remove_from_settings" msgid="8389591916603406378">"Aus \"Einstellungen\" entfernen"</string>
     <string name="remove_from_settings_prompt" msgid="6069085993355887748">"System UI Tuner aus \"Einstellungen\" entfernen und die Verwendung von allen zugehörigen Funktionen beenden?"</string>
-    <string name="activity_not_found" msgid="348423244327799974">"Die App ist nicht auf Ihrem Gerät installiert."</string>
+    <string name="activity_not_found" msgid="348423244327799974">"Die App ist nicht auf deinem Gerät installiert."</string>
     <string name="clock_seconds" msgid="7689554147579179507">"Uhrsekunden anzeigen"</string>
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Uhrsekunden in der Statusleiste anzeigen. Kann sich auf die Akkulaufzeit auswirken."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Schnelleinstellungen neu anordnen"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startseite"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Letzte"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Zurück"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings_tv.xml b/packages/SystemUI/res/values-de/strings_tv.xml
new file mode 100644
index 0000000..66e3e01
--- /dev/null
+++ b/packages/SystemUI/res/values-de/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"PiP schließen"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Vollbild"</string>
+    <string name="pip_play" msgid="674145557658227044">"Wiedergeben"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Pausieren"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Abbrechen"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Halte STARTSEITE gedrückt, um das PiP zu steuern."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index ec47e68..f128544 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Πλήρης\nσίγαση"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Μόνο\nπροτεραιότητας"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Μόνο\nειδοποιήσεις"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Όλα"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Αρχική οθόνη"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Πρόσφατα"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Πίσω"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings_tv.xml b/packages/SystemUI/res/values-el/strings_tv.xml
new file mode 100644
index 0000000..7239386
--- /dev/null
+++ b/packages/SystemUI/res/values-el/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Κλείσιμο PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Πλήρης οθόνη"</string>
+    <string name="pip_play" msgid="674145557658227044">"Αναπαραγωγή"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Παύση"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Ακύρωση"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Κρατήστε το πλήκτρο HOME πατημένο για να ελέγξετε το PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index fca0b78..38f3d38 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -331,6 +331,8 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Total\nsilence"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Priority\nonly"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Alarms\nonly"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"All"</string>
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"All\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Charging (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Charging rapidly (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Charging slowly (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
@@ -480,4 +482,9 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recent"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Back"</string>
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Show Do Not Disturb in volume"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Allow full control of Do Not Disturb in the volume dialogue."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volume and Do Not Disturb"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Enter Do Not Disturb on volume down"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Exit Do Not Disturb on volume up"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index fca0b78..38f3d38 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -331,6 +331,8 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Total\nsilence"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Priority\nonly"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Alarms\nonly"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"All"</string>
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"All\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Charging (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Charging rapidly (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Charging slowly (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
@@ -480,4 +482,9 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recent"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Back"</string>
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Show Do Not Disturb in volume"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Allow full control of Do Not Disturb in the volume dialogue."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volume and Do Not Disturb"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Enter Do Not Disturb on volume down"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Exit Do Not Disturb on volume up"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index fca0b78..38f3d38 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -331,6 +331,8 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Total\nsilence"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Priority\nonly"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Alarms\nonly"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"All"</string>
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"All\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Charging (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Charging rapidly (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Charging slowly (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
@@ -480,4 +482,9 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recent"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Back"</string>
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Show Do Not Disturb in volume"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Allow full control of Do Not Disturb in the volume dialogue."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volume and Do Not Disturb"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Enter Do Not Disturb on volume down"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Exit Do Not Disturb on volume up"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index a532932..c521912 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Silencio\ntotal"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Solo\nprioridad"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Solo\nalarmas"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Todo"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Cargando (faltan <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para completar)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Carga rápida (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para completar la carga)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Carga lenta (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para completar la carga)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Pantalla principal"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recientes"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Atrás"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings_tv.xml b/packages/SystemUI/res/values-es-rUS/strings_tv.xml
new file mode 100644
index 0000000..9b0a055
--- /dev/null
+++ b/packages/SystemUI/res/values-es-rUS/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Cerrar PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Pantalla completa"</string>
+    <string name="pip_play" msgid="674145557658227044">"Reproducir"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Pausar"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Cancelar"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Mantén presionado el botón INICIO para controlar PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 88c31d6..8d98049 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -331,6 +331,8 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Silencio\ntotal"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Solo\ncon prioridad"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Solo\nalarmas"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Todo"</string>
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Todo\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Cargando (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para completar)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Cargando rápidamente (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hasta completar)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Cargando lentamente (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hasta completar)"</string>
@@ -480,4 +482,9 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Inicio"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recientes"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Atrás"</string>
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Mostrar el panel de control de No molestar en el volumen"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Permitir un control total del modo No molestar en el cuadro de diálogo de volumen."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volumen y No molestar"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Activar No molestar al bajar el volumen"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Salir de No molestar al subir el volumen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings_tv.xml b/packages/SystemUI/res/values-es/strings_tv.xml
new file mode 100644
index 0000000..b9649f9
--- /dev/null
+++ b/packages/SystemUI/res/values-es/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Cerrar PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Pantalla completa"</string>
+    <string name="pip_play" msgid="674145557658227044">"Reproducir"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Pausar"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Cancelar"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Mantén pulsado el botón INICIO para controlar PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index fcf9752..126bc12 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -331,6 +331,8 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Täielik\nvaikus"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Ainult\nprioriteetsed"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Ainult\nalarmid"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Kõik"</string>
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Kõik\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Laadimine (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>, kuni seade on täis)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Kiirlaadimine (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>, kuni seade on täis)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Aeglane laadimine (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>, kuni seade on täis)"</string>
@@ -480,4 +482,9 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Avaekraan"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Hiljutised"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Tagasi"</string>
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Kuva helitugevuse juures funktsioon Mitte segada"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Helitugevuse dialoogis lubatakse funktsiooni Mitte segada täielik juhtimine."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Helitugevus ja funktsioon Mitte segada"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Lülita helitugevuse vähendamisel sisse funkt. Mitte segada"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Lülita helitugevuse suurendamisel välja funkt. Mitte segada"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et-rEE/strings_tv.xml b/packages/SystemUI/res/values-et-rEE/strings_tv.xml
new file mode 100644
index 0000000..8af5984
--- /dev/null
+++ b/packages/SystemUI/res/values-et-rEE/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Sule PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Täisekraan"</string>
+    <string name="pip_play" msgid="674145557658227044">"Esita"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Peata"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Tühista"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"PIP juhtimiseks hoidke all nuppu AVAEKRAAN"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index 02c4574..54154ea 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Isiltasun\nosoa"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Lehentasunezkoak\nsoilik"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Alarmak\nsoilik"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Guztiak"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Kargatzen (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> guztiz kargatu arte)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Bizkor kargatzen (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> guztiz kargatu arte)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Mantso kargatzen (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> guztiz kargatu arte)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Hasierako pantaila"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Azkenak"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Atzera"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-eu-rES/strings_tv.xml b/packages/SystemUI/res/values-eu-rES/strings_tv.xml
new file mode 100644
index 0000000..be2053e
--- /dev/null
+++ b/packages/SystemUI/res/values-eu-rES/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Itxi pantaila txikia"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Pantaila osoa"</string>
+    <string name="pip_play" msgid="674145557658227044">"Erreproduzitu"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Pausatu"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Utzi"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Eduki sakatuta hasierako botoia pantaila txikia kontrolatzeko"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index e6508de..da13225 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"سکوت\nکامل"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"فقط\nاولویت‌دار"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"فقط\nهشدارها"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"همه"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"صفحه اصلی"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"موارد اخیر"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"برگشت"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings_tv.xml b/packages/SystemUI/res/values-fa/strings_tv.xml
new file mode 100644
index 0000000..b7c4e61
--- /dev/null
+++ b/packages/SystemUI/res/values-fa/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"‏بستن PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"تمام صفحه"</string>
+    <string name="pip_play" msgid="674145557658227044">"پخش"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"مکث"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"لغو"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"‏نگه‌داشتن HOME برای کنترل PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index ed5d6f4..8e89737 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Täydellinen\nhiljaisuus"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Vain\ntärkeät"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Vain\nherätykset"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Kaikki"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Ladataan (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> kunnes täynnä)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Nopea lataus (latausaikaa jäljellä <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Hidas lataus (latausaikaa jäljellä <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Aloitusnäyttö"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Viimeaikaiset"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Takaisin"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings_tv.xml b/packages/SystemUI/res/values-fi/strings_tv.xml
new file mode 100644
index 0000000..d39c37f
--- /dev/null
+++ b/packages/SystemUI/res/values-fi/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Sulje PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Koko näyttö"</string>
+    <string name="pip_play" msgid="674145557658227044">"Toista"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Keskeytä"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Peruuta"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Hallinnoi PIP-tilaa painamalla Aloitusnäyttö-painiketta pitkään."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 0608044..b61a260 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Aucune\ninterruption"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Priorités\nuniquement"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Alarmes\nuniquement"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Tous"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Charge en cours... (chargée à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Charge rapide en cours... (chargé dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Charge lente en cours... (chargé dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Accueil"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Récents"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Précédent"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings_tv.xml b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml
new file mode 100644
index 0000000..c06e492
--- /dev/null
+++ b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Fermer le mode PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Plein écran"</string>
+    <string name="pip_play" msgid="674145557658227044">"Lecture"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Interrompre"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Annuler"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Maintenez enfoncée la touche ACCUEIL gérer le mode PIP."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index b9d7c32..3d02297 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Aucune\ninterruption"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Priorité\nuniquement"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Alarmes\nuniquement"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Toujours"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Charge en cours… (chargé à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Charge rapide… (chargé à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Charge lente… (chargé à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Accueil"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Récents"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Précédent"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings_tv.xml b/packages/SystemUI/res/values-fr/strings_tv.xml
new file mode 100644
index 0000000..bf7306e
--- /dev/null
+++ b/packages/SystemUI/res/values-fr/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Fermer le mode PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Plein écran"</string>
+    <string name="pip_play" msgid="674145557658227044">"Lire"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Suspendre"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Annuler"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Appuyez de manière prolongée sur \"ACCUEIL\" pour contrôler le mode PIP."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index 5d0ab01..b69219b 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Silencio\ntotal"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Só\nprioridade"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Só\nalarmas"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Todas"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Cargando (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para finalizar a carga)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Cargando rápido (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para rematar a carga)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Cargando lento (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para rematar a carga)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Inicio"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Volver"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-gl-rES/strings_tv.xml b/packages/SystemUI/res/values-gl-rES/strings_tv.xml
new file mode 100644
index 0000000..857911d
--- /dev/null
+++ b/packages/SystemUI/res/values-gl-rES/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Pechar PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Pantalla completa"</string>
+    <string name="pip_play" msgid="674145557658227044">"Reproducir"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Pausar"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Cancelar"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Manter premido INICIO para controlar PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml
index 7fcd651..1211e7b 100644
--- a/packages/SystemUI/res/values-gu-rIN/strings.xml
+++ b/packages/SystemUI/res/values-gu-rIN/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"સાવ\nશાંતિ"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ફક્ત\nપ્રાધાન્યતા"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"ફક્ત\nએલાર્મ્સ"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"તમામ"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"હોમ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"તાજેતરના"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"પાછળ"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 8af6e03..7e70dee 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -331,6 +331,8 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"पूरी तरह\nशांत"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"केवल\nप्राथमिकता"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"केवल\nअलार्म"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"सभी"</string>
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"सभी\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>
@@ -480,4 +482,9 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"होम"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"हाल ही के"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"वापस जाएं"</string>
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"वॉल्यूम में परेशान न करें दिखाएं"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"वॉल्यूम संवाद में परेशान न करें के पूर्ण नियंत्रण की अनुमति दें."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"वॉल्यूम और परेशान न करें"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"वॉल्यूम कम करें पर परेशान न करें डालें"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"वॉल्यूम बढ़ाएं पर परेशान न करें से बाहर निकलें"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 495f504..23cb96b 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -332,6 +332,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Potpuna\ntišina"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Samo\nprioritetno"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Samo\nalarmi"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Sve"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Punjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do napunjenosti)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Brzo punjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do napunjenosti)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Sporo punjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do napunjenosti)"</string>
@@ -481,4 +484,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Početni zaslon"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Najnovije"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Natrag"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings_tv.xml b/packages/SystemUI/res/values-hr/strings_tv.xml
new file mode 100644
index 0000000..e87d880
--- /dev/null
+++ b/packages/SystemUI/res/values-hr/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Zatvori PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Cijeli zaslon"</string>
+    <string name="pip_play" msgid="674145557658227044">"Reproduciraj"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Pauziraj"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Odustani"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Držite POČETNI ZASLON da biste kontrolirali PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index c96ac98..84454f6 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -331,6 +331,8 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Teljes\nnémítás"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Csak\nprioritás"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Csak\nriasztások"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Összes"</string>
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Összes\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Töltés (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> a teljes töltöttségig)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Gyors töltés (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> a teljes töltöttségig)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Lassú töltés (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> a teljes töltöttségig)"</string>
@@ -480,4 +482,9 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Otthon"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Legutóbbiak"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Vissza"</string>
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"A „Ne zavarjanak” funkció megjelenítése a hangvezérlőben"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"A „Ne zavarjanak” funkció teljes körű vezérlésének engedélyezése a hangerővezérlési párbeszédpanelon."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Hangvezérlő és „Ne zavarjanak” funkció"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"„Ne zavarjanak” aktiválása hangerőcsökkentéskor"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"„Ne zavarjanak” deaktiválása hangerőnöveléskor"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index e819470..89045e1 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Ընդհանուր\nլուռ վիճակը"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Միայն\nկարևորները"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Միայն\nզարթուցիչ"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Բոլորը"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Գլխավոր էջ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Վերջինները"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Հետ"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings_tv.xml b/packages/SystemUI/res/values-hy-rAM/strings_tv.xml
new file mode 100644
index 0000000..8113f09
--- /dev/null
+++ b/packages/SystemUI/res/values-hy-rAM/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Փակել PIP-ն"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Լիէկրան"</string>
+    <string name="pip_play" msgid="674145557658227044">"Նվագարկել"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Դադարեցնել"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Չեղարկել"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"PIP-ն կառավարելու համար սեղմած պահեք HOME կոճակը"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 3538404..b7ac86d 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Senyap\ntotal"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Hanya\nprioritas"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Hanya\nalarm"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Semua"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Mengisi daya (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hingga penuh)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Mengisi daya dengan cepat (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hingga penuh)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Mengisi daya dengan lambat (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hingga penuh)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Layar Utama"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Terbaru"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Kembali"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index 7f580a5..cb2a3bd 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Algjör\nþögn"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Aðeins\nforgangur"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Aðeins\nvekjarar"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Allar"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Í hleðslu (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> fram að fullri hleðslu)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Í hraðri hleðslu (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> fram að fullri hleðslu)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Í hægri hleðslu (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> fram að fullri hleðslu)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Heim"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nýlegt"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Til baka"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-is-rIS/strings_tv.xml b/packages/SystemUI/res/values-is-rIS/strings_tv.xml
new file mode 100644
index 0000000..d91605e
--- /dev/null
+++ b/packages/SystemUI/res/values-is-rIS/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Loka PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Allur skjárinn"</string>
+    <string name="pip_play" msgid="674145557658227044">"Spila"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Hlé"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Hætta við"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Haltu HOME-lyklinum niðri til að stjórna PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 30d214e..998230d 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Silenzio\ntotale"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Solo con\npriorità"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Solo\nsveglie"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Tutte"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"In carica (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> al termine)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Ricarica veloce (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> al termine)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Ricarica lenta (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> al termine)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recenti"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Indietro"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 95a2349..af5edb4 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -333,6 +333,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"שקט\nמוחלט"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"התראות בעדיפות\nבלבד"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"התראות\nבלבד"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"הכל"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -482,4 +485,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"דף הבית"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"אחרונים"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"הקודם"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings_tv.xml b/packages/SystemUI/res/values-iw/strings_tv.xml
new file mode 100644
index 0000000..a1bebb9
--- /dev/null
+++ b/packages/SystemUI/res/values-iw/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"‏סגור PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"מסך מלא"</string>
+    <string name="pip_play" msgid="674145557658227044">"הפעל"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"השהה"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"ביטול"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"‏המשך ללחוץ על HOME כדי לשלוט ב-PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 6be39df..5f448bf 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"サイレント\n"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"重要な\n通知のみ"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"アラーム\nのみ"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"すべて"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ホーム"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"最近"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"戻る"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings_tv.xml b/packages/SystemUI/res/values-ja/strings_tv.xml
new file mode 100644
index 0000000..08a5a1c
--- /dev/null
+++ b/packages/SystemUI/res/values-ja/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"PIP を閉じる"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"全画面表示"</string>
+    <string name="pip_play" msgid="674145557658227044">"再生"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"一時停止"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"キャンセル"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"[ホーム] を押し続けると PIP を制御できます"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 35d3a37..38fd4b3 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"სრული\nსიჩუმე"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"მხოლოდ\nპრიორიტეტულები"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"მხოლოდ\nგაფრთხილებები"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"ყველა"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"მთავარი"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ბოლოს გამოყენებული"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"უკან"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings_tv.xml b/packages/SystemUI/res/values-ka-rGE/strings_tv.xml
new file mode 100644
index 0000000..83db37b
--- /dev/null
+++ b/packages/SystemUI/res/values-ka-rGE/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"PIP-ის დახურვა"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"სრულ ეკრანზე"</string>
+    <string name="pip_play" msgid="674145557658227044">"დაკვრა"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"პაუზა"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"გაუქმება"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"PIP-ის სამართავად, ხანგრძლივად დააჭირეთ მთავარ ღილაკს"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index cc8edd4..f1d96b2 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Толық\nтыныштық"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Тек\nбасымдық"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Тек\nдабылдар"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Барлығы"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Негізгі бет"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Жақындағылар"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Артқа"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 28ed206..7f5b0d8 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"ស្ងៀមស្ងាត់\nទាំងស្រុង"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"អាទិភាព\nប៉ុណ្ណោះ"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"សំឡេងរោទ៍\nប៉ុណ្ណោះ"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"ទាំងអស់"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ដើម"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ថ្មីៗ"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"ថយក្រោយ"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index 8d19b44..e238e53 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"ಸಂಪೂರ್ಣ\nನಿಶ್ಯಬ್ಧ"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ಆದ್ಯತೆ\nಮಾತ್ರ"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"ಅಲಾರಮ್‌ಗಳು\nಮಾತ್ರ"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"ಎಲ್ಲ"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ಮುಖಪುಟ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ಇತ್ತೀಚಿನವುಗಳು"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"ಹಿಂದೆ"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index a8b96869..725bd18 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"모두\n차단"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"중요 알림만\n허용"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"알람만\n"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"모두 수신"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"홈"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"최근"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"뒤로"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings_tv.xml b/packages/SystemUI/res/values-ko/strings_tv.xml
new file mode 100644
index 0000000..158f4ad
--- /dev/null
+++ b/packages/SystemUI/res/values-ko/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"PIP 닫기"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"전체화면"</string>
+    <string name="pip_play" msgid="674145557658227044">"재생"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"일시중지"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"취소"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"PIP를 제어하려면 홈을 누르세요."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index eb47f27..539cc7e 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Тым-\nтырс"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Артыкчылыктуу\nгана"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Ойготкучтар\nгана"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Бардыгы"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Башкы бет"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Акыркылар"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Артка"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings_tv.xml b/packages/SystemUI/res/values-ky-rKG/strings_tv.xml
new file mode 100644
index 0000000..c54d0d2
--- /dev/null
+++ b/packages/SystemUI/res/values-ky-rKG/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"PIP жабуу"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Толук экран"</string>
+    <string name="pip_play" msgid="674145557658227044">"Ойнотуу"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Тындыруу"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Жокко чыгаруу"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"PIP көзөмөлдөө үчүн БАШКЫ БЕТ баскычын кармап туруңуз"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-land/config.xml b/packages/SystemUI/res/values-land/config.xml
index 43e7bac..e0affa1 100644
--- a/packages/SystemUI/res/values-land/config.xml
+++ b/packages/SystemUI/res/values-land/config.xml
@@ -38,4 +38,6 @@
          while the stack is not focused. -->
     <item name="recents_layout_unfocused_range_min" format="float" type="integer">-2</item>
     <item name="recents_layout_unfocused_range_max" format="float" type="integer">1.5</item>
+
+    <integer name="quick_settings_num_columns">4</integer>
 </resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index f162be3..b75e398 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"ຄວາມ​ງຽບ\nທັງ​ໝົດ"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ບຸ​ລິ​ມະ​ສິດ\nເທົ່າ​ນັ້ນ"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"ໂມງ​ປຸກ\nເທົ່າ​ນັ້ນ"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"ທັງໝົດ"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"​ໜ້າຫຼັກ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ຫາ​ກໍ​ໃຊ້"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"ກັບຄືນ"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings_tv.xml b/packages/SystemUI/res/values-lo-rLA/strings_tv.xml
new file mode 100644
index 0000000..289d4e2
--- /dev/null
+++ b/packages/SystemUI/res/values-lo-rLA/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"ປິດ PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"ເຕັມໜ້າຈໍ"</string>
+    <string name="pip_play" msgid="674145557658227044">"ຫຼິ້ນ"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"ຢຸດຊົ່ວຄາວ"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"ຍົກເລີກ"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"ກົດຄ້າງປຸ່ມ HOME ເພື່ອຄວບຄຸມ PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index c0063a5..e79e6d3 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -333,6 +333,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Visiška\ntyla"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Tik\nprioritetiniai"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Tik\nsignalai"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Visi"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Kraunama (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> iki visiško įkrovimo)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Greitai kraunama (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> iki visiško įkrovimo)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Lėtai kraunama (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> iki visiško įkrovimo)"</string>
@@ -482,4 +485,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Pagrindinis ekranas"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Naujausios veiklos ekranas"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Atgal"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 90f5d1e..3b27424 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -332,6 +332,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Pilnīgs\nklusums"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Tikai\nprioritārie"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Tikai\nsignāli"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Visi"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Notiek uzlāde (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> līdz pilnīgai uzlādei)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Ātra uzlāde (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> līdz pilnīgai uzlādei)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Lēna uzlāde (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> līdz pilnīgai uzlādei)"</string>
@@ -481,4 +484,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Sākums"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Pēdējie"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Atpakaļ"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings_tv.xml b/packages/SystemUI/res/values-lv/strings_tv.xml
new file mode 100644
index 0000000..1c42520
--- /dev/null
+++ b/packages/SystemUI/res/values-lv/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Aizvērt attēlu attēlā"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Pilnekrāna režīms"</string>
+    <string name="pip_play" msgid="674145557658227044">"Atskaņot"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Apturēt"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Atcelt"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Turiet nospiestu taustiņu HOME, lai kontrolētu attēlu attēlā"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml
index 275ea07..85832df 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -331,6 +331,8 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Целосна\nтишина"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Само\nприоритетни"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Само\nаларми"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Сѐ"</string>
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Сите\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>
@@ -480,4 +482,9 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Почетна страница"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Неодамнешни"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Назад"</string>
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Прикажи „Не вознемирувај“ во јачината на звукот"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Дозволете целосна контрола на „Не вознемирувај“ во дијалогот за јачина на звукот."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Јачина на звук и „Не вознемирувај“"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Премини во „Не вознемирувај“ при намалена јачина на звукот"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Излези од „Не вознемирувај“ при зголемена јачина на звукот"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings_tv.xml b/packages/SystemUI/res/values-mk-rMK/strings_tv.xml
new file mode 100644
index 0000000..ce7a13a
--- /dev/null
+++ b/packages/SystemUI/res/values-mk-rMK/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Затвори ја слика во слика"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Цел екран"</string>
+    <string name="pip_play" msgid="674145557658227044">"Пушти"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Пауза"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Откажи"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Задржете ја Почетна страница за да ја контролирате Слика во слика"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml
index 0af709f..b2d7b9d 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"പൂർണ്ണ\nനിശബ്‌ദത"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"മുൻഗണന\nമാത്രം"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"അലാറങ്ങൾ\nമാത്രം"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"എല്ലാം"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"വീട്"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"പുതിയവ"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"മടങ്ങുക"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings_tv.xml b/packages/SystemUI/res/values-ml-rIN/strings_tv.xml
new file mode 100644
index 0000000..4bb15fb
--- /dev/null
+++ b/packages/SystemUI/res/values-ml-rIN/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"PIP അടയ്ക്കുക"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"പൂര്‍ണ്ണ സ്ക്രീന്‍"</string>
+    <string name="pip_play" msgid="674145557658227044">"പ്ലേ ചെയ്യുക"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"തൽക്കാലം നിർത്തൂ"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"റദ്ദാക്കുക"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"PIP നിയന്ത്രിക്കാൻ ഹോം പിടിക്കുക"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index f3982cc..2e8126e 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -329,6 +329,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Дуугүй\nболгох"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Зөвхөн\nхамгийн чухлыг"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Зөвхөн\nсэрүүлэг"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Бүгд"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -478,4 +481,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Нүүр хуудас"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Саяхны"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Буцах"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings_tv.xml b/packages/SystemUI/res/values-mn-rMN/strings_tv.xml
new file mode 100644
index 0000000..04df731
--- /dev/null
+++ b/packages/SystemUI/res/values-mn-rMN/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"PIP-г хаах"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Бүтэн дэлгэц"</string>
+    <string name="pip_play" msgid="674145557658227044">"Тоглуулах"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Түр зогсоох"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Цуцлах"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"PIP-г удирдахын тулд HOME-г дарна уу"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index f9bfe41..846e7ee 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"संपूर्ण\nशांतता"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"केवळ\nप्राधान्य"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"केवळ\nअलार्म"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"सर्व"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"मुख्यपृष्ठ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"अलीकडील"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"परत"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings_tv.xml b/packages/SystemUI/res/values-mr-rIN/strings_tv.xml
new file mode 100644
index 0000000..021f34c
--- /dev/null
+++ b/packages/SystemUI/res/values-mr-rIN/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"PIP बंद करा"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"पूर्ण स्क्रीन"</string>
+    <string name="pip_play" msgid="674145557658227044">"प्ले करा"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"विराम द्या"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"रद्द करा"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"PIP नियंत्रित करण्‍यासाठी मुख्‍यपृष्‍ठ धरून ठेवा"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index 9167550..dd5f767 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Senyap\nsepenuhnya"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Keutamaan\nsahaja"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Penggera\nsahaja"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Semua"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Mengecas (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> sehingga penuh)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Mengecas cepat (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> sehingga penuh)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Mengecas perlahan (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> sehingga penuh)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Skrin Utama"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Terbaharu"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Kembali"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings_tv.xml b/packages/SystemUI/res/values-ms-rMY/strings_tv.xml
new file mode 100644
index 0000000..850910b
--- /dev/null
+++ b/packages/SystemUI/res/values-ms-rMY/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Tutup PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Skrin penuh"</string>
+    <string name="pip_play" msgid="674145557658227044">"Main"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Jeda"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Batal"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Tahan kekunci HOME untuk mengawal PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index 8801f96..4bb3a45 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"လုံးဝ\nတိတ်ဆိတ်ခြင်း"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ဦးစားပေးမှု\nသာ"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"နှိုးစက်များ\nသာ"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"အားလုံး"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ပင်မ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"မကြာသေးခင်က"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"နောက်သို့"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 684c9ce..87b2b54 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Total\nstillhet"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Bare\nPrioritet"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Bare\nalarmer"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Alle"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Lader (fulladet om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Lader raskt (fulladet om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Lader sakte (fulladet om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startside"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nylige"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Tilbake"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings_tv.xml b/packages/SystemUI/res/values-nb/strings_tv.xml
new file mode 100644
index 0000000..ba191a4
--- /dev/null
+++ b/packages/SystemUI/res/values-nb/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Lukk PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Fullskjerm"</string>
+    <string name="pip_play" msgid="674145557658227044">"Spill av"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Sett på pause"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Avbryt"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Hold inne STARTSIDEN for å kontrollere PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index fc12608..a56a701 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"पूरै\nशान्त"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"प्राथमिकता \nमात्र"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"अलार्महरू \nमात्र"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"सबै"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"गृह"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"हालैका"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"पछाडि"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index b7b2fc0..a811db3 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -331,6 +331,8 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Totale\nstilte"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Alleen\nprioriteit"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Alleen\nalarmen"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Alle"</string>
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Alle\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Opladen (vol over <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Snel opladen (vol over <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Langzaam opladen (vol over <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -480,4 +482,9 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startpagina"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recent"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Terug"</string>
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"\'Niet storen\' weergeven in volume"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Volledig beheer van \'Niet storen\' in het volumedialoogvenster toestaan."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volume en \'Niet storen\'"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"\'Niet storen\' activeren bij volume omlaag"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"\'Niet storen\' afsluiten bij volume omhoog"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml
index d77c245..f3c85eb 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings.xml
@@ -331,6 +331,8 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"ਕੁਲ \n ਚੁੱਪੀ"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ਕੇਵਲ\nਤਰਜੀਹੀ"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"ਕੇਵਲ\nਅਲਾਰਮ"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"ਸਭ"</string>
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"ਸਾਰੀਆਂ\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>
@@ -480,4 +482,9 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ਮੁੱਖ ਸਕ੍ਰੀਨ"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ਹਾਲੀਆ"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"ਪਿੱਛੇ"</string>
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"ਵੌਲਯੂਮ ਵਿੱਚ ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਵਿਖਾਓ"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"ਵੌਲਯੂਮ ਡਾਇਲੌਗ ਵਿੱਚ ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਦੇ ਪੂਰੇ ਨਿਯੰਤ੍ਰਣ ਦੀ ਮਨਜ਼ੂਰੀ ਦਿਓ।"</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"ਵੌਲਯੂਮ ਅਤੇ ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"ਵੌਲਯੂਮ ਘੱਟ ਹੋਣ \'ਤੇ ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"ਵੌਲਯੂਮ ਉੱਚੀ ਹੋਣ \'ਤੇ ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਤੋਂ ਬਾਹਰ ਜਾਓ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index eed825a..4224730 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -333,6 +333,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Całkowita\ncisza"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Tylko\npriorytetowe"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Tylko\nalarmy"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Wszystkie"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Ładuje się (pełne naładowanie za <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Szybkie ładowanie (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do końca)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Wolne ładowanie (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do końca)"</string>
@@ -482,4 +485,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ekran główny"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Ostatnie"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Wstecz"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings_tv.xml b/packages/SystemUI/res/values-pl/strings_tv.xml
new file mode 100644
index 0000000..270ef86
--- /dev/null
+++ b/packages/SystemUI/res/values-pl/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Zamknij PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Pełny ekran"</string>
+    <string name="pip_play" msgid="674145557658227044">"Odtwórz"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Wstrzymaj"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Anuluj"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Przytrzymaj przycisk STRONA GŁÓWNA, by sterować PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index d9b1157..d81fd8a 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Silêncio\ntotal"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Somente\nprioridade"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Somente\nalarmes"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Tudo"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Carregando (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> até concluir)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Carregando rapidamente (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para conclusão)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Carregando lentamente (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para conclusão)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Início"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Voltar"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings_tv.xml b/packages/SystemUI/res/values-pt-rBR/strings_tv.xml
new file mode 100644
index 0000000..131507c
--- /dev/null
+++ b/packages/SystemUI/res/values-pt-rBR/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Fechar PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Tela cheia"</string>
+    <string name="pip_play" msgid="674145557658227044">"Reproduzir"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Pausar"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Cancelar"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Mantenha \"PÁGINA INICIAL\" pressionado para controlar o PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 4470433..bfaf659 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Silêncio\ntotal"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Apenas\nprioridade"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Apenas\nalarmes"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Tudo"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"A carregar (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> até à carga máxima)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"A carregar rapid. (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> até à carga máxima)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"A carregar lentam. (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> até à carga máxima)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Página inicial"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Anterior"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings_tv.xml b/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
new file mode 100644
index 0000000..5b4567e
--- /dev/null
+++ b/packages/SystemUI/res/values-pt-rPT/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Fechar PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Ecrã inteiro"</string>
+    <string name="pip_play" msgid="674145557658227044">"Reproduzir"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Interromper"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Cancelar"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Prima sem soltar HOME para controlar o PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index d9b1157..d81fd8a 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Silêncio\ntotal"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Somente\nprioridade"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Somente\nalarmes"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Tudo"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Carregando (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> até concluir)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Carregando rapidamente (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para conclusão)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Carregando lentamente (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para conclusão)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Início"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Voltar"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings_tv.xml b/packages/SystemUI/res/values-pt/strings_tv.xml
new file mode 100644
index 0000000..131507c
--- /dev/null
+++ b/packages/SystemUI/res/values-pt/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Fechar PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Tela cheia"</string>
+    <string name="pip_play" msgid="674145557658227044">"Reproduzir"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Pausar"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Cancelar"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Mantenha \"PÁGINA INICIAL\" pressionado para controlar o PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 2a4304e..484a1b8 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -332,6 +332,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Niciun\nsunet"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Numai\ncu prioritate"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Numai\nalarme"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Toate"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Se încarcă (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> până la finalizare)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Se încarcă rapid (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> până la finalizare)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Se încarcă lent (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> până la finalizare)"</string>
@@ -481,4 +484,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ecran de pornire"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recente"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Înapoi"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings_tv.xml b/packages/SystemUI/res/values-ro/strings_tv.xml
new file mode 100644
index 0000000..b3cd663
--- /dev/null
+++ b/packages/SystemUI/res/values-ro/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Închideți PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Ecran complet"</string>
+    <string name="pip_play" msgid="674145557658227044">"Redați"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Întrerupeți"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Anulați"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Pentru a controla PIP, atingeți lung ECRAN DE PORNIRE"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 031864d..0876366 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -333,6 +333,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Полная\nтишина"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Только\nважные"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Только\nбудильник"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Все"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -482,4 +485,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Главный экран"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Недавние"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Назад"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings_tv.xml b/packages/SystemUI/res/values-ru/strings_tv.xml
new file mode 100644
index 0000000..35ecb1c
--- /dev/null
+++ b/packages/SystemUI/res/values-ru/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Выйти из режима \"Кадр в кадре\""</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Во весь экран"</string>
+    <string name="pip_play" msgid="674145557658227044">"Воспроизвести"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Приостановить"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Отмена"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Управляйте режимом \"Кадр в кадре\", удерживая кнопку ГЛАВНАЯ"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index 918bf13..4520aef 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"සම්පූර්ණ\nනිහඬතාව"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ප්‍රමුඛතා\nපමණි"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"ඇඟවීම්\nපමණි"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"සියලු"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"මුල් පිටුව"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"මෑත"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"ආපසු"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-si-rLK/strings_tv.xml b/packages/SystemUI/res/values-si-rLK/strings_tv.xml
new file mode 100644
index 0000000..fe51cc8
--- /dev/null
+++ b/packages/SystemUI/res/values-si-rLK/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"PIP වසන්න"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"පූර්ණ තිරය"</string>
+    <string name="pip_play" msgid="674145557658227044">"ධාවනය කරන්න"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"විරාමය"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"අවලංගු කරන්න"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"PIP පාලනය කිරීමට HOME අල්ලාගෙන සිටින්න"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 0ac2154..7458212 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -333,6 +333,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Úplné\nticho"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Iba\nprioritné"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Iba\nbudíky"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Všetky"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Nabíja sa (úplné nabitie o <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Nabíja sa rýchlo (úplné nabitie o <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Nabíja sa pomaly (úplné nabitie o <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -482,4 +485,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Domovská stránka"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedávne"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Späť"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings_tv.xml b/packages/SystemUI/res/values-sk/strings_tv.xml
new file mode 100644
index 0000000..24c42d1
--- /dev/null
+++ b/packages/SystemUI/res/values-sk/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Zavrieť režim PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Celá obrazovka"</string>
+    <string name="pip_play" msgid="674145557658227044">"Prehrať"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Pozastaviť"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Zrušiť"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Ak chcete ovládať režim PIP, podržte tlačidlo plochy"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 7274abd..59037a8 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -333,6 +333,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Popolna\ntišina"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Samo\nprednostno"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Samo\nalarmi"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Vse"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Polnjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do napolnjenosti)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Hitro polnjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do napolnjenosti)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Počasno polnjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do napolnjenosti)"</string>
@@ -482,4 +485,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Začetni zaslon"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedavni"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Nazaj"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings_tv.xml b/packages/SystemUI/res/values-sl/strings_tv.xml
new file mode 100644
index 0000000..28e9d98
--- /dev/null
+++ b/packages/SystemUI/res/values-sl/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Zapri način PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Celozaslonsko"</string>
+    <string name="pip_play" msgid="674145557658227044">"Predvajanje"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Zaustavitev"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Prekliči"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Pridržite tipko HOME za upravljanje načina PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml
index f50d64c..7dcad4e 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings.xml
@@ -331,6 +331,8 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Heshtje\ne plotë"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Vetëm\nme prioritet"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Vetëm\nalarmet"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Të gjitha"</string>
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Të gjitha\n"</string>
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Po ngarkohet (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> deri sa të mbushet)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Po ngarkon me shpejtësi (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> derisa të mbushet)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Po ngarkon me ngadalë (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> derisa të mbushet)"</string>
@@ -480,4 +482,9 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Kreu"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Të fundit"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Prapa"</string>
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Shfaq \"Mos shqetëso\" te volumi"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Lejo kontrollin e plotë të opsionit \"Mos shqetëso\" në dialogun e volumit."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Volumi dhe \"Mos shqetëso\""</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Vendos \"Mos shqetëso\" me volumin poshtë"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Dil nga \"Mos shqetëso\" me volumin lart"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings_tv.xml b/packages/SystemUI/res/values-sq-rAL/strings_tv.xml
new file mode 100644
index 0000000..31298a4
--- /dev/null
+++ b/packages/SystemUI/res/values-sq-rAL/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Mbyll PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Ekrani i plotë"</string>
+    <string name="pip_play" msgid="674145557658227044">"Luaj"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Pauzë"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Anulo"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Mbaj shtypur HOME për të kontrolluar PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 4ab521c..d6a4359 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -332,6 +332,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Потпуна\nтишина"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Само\nприорит. прекиди"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Само\nаларми"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Све"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -481,4 +484,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Почетни"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Недавни садржај"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Назад"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings_tv.xml b/packages/SystemUI/res/values-sr/strings_tv.xml
new file mode 100644
index 0000000..3c6b59e
--- /dev/null
+++ b/packages/SystemUI/res/values-sr/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Затвори PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Цео екран"</string>
+    <string name="pip_play" msgid="674145557658227044">"Пусти"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Паузирај"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Откажи"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Задржите тастер за ПОЧЕТНИ ЕКРАН да бисте контролисали PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index f23ac52..4d8a0e3 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Helt\ntyst"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Endast\nprioriterade"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Endast\nalarm"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Alla"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Laddar (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> tills batteriet är fulladdat)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Laddas snabbt (batteriet fulladdat om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Laddas sakta (batteriet fulladdat om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startsida"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Senaste"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Tillbaka"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings_tv.xml b/packages/SystemUI/res/values-sv/strings_tv.xml
new file mode 100644
index 0000000..b36c19f
--- /dev/null
+++ b/packages/SystemUI/res/values-sv/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Stäng PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Helskärm"</string>
+    <string name="pip_play" msgid="674145557658227044">"Spela upp"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Pausa"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Avbryt"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Håll ned HOME om du vill styra PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 59282da..97b1a3d 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Kimya\nkabisa"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Kipaumbele\npekee"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Kengele\npekee"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Zote"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Inachaji (Imebakisha <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ijae)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Inachaji kwa kasi (itajaa baada ya <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Inachaji pole pole (itajaa baada ya <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Mwanzo"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Zilizotumika majuzi"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Nyuma"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings_tv.xml b/packages/SystemUI/res/values-sw/strings_tv.xml
new file mode 100644
index 0000000..fc0f414
--- /dev/null
+++ b/packages/SystemUI/res/values-sw/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Funga PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Skrini nzima"</string>
+    <string name="pip_play" msgid="674145557658227044">"Cheza"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Sitisha"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Ghairi"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Shikilia kitufe cha HOME ili udhibiti PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-sw600dp-land/config.xml b/packages/SystemUI/res/values-sw600dp-land/config.xml
index f9b01c8..7e8d802 100644
--- a/packages/SystemUI/res/values-sw600dp-land/config.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/config.xml
@@ -18,4 +18,6 @@
     <!-- The maximum count of notifications on Keyguard. The rest will be collapsed in an overflow
          card. -->
     <integer name="keyguard_max_notification_count">3</integer>
+
+    <integer name="quick_settings_num_columns">3</integer>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml
index 6795da4..17ff195 100644
--- a/packages/SystemUI/res/values-sw600dp/config.xml
+++ b/packages/SystemUI/res/values-sw600dp/config.xml
@@ -35,7 +35,7 @@
 
     <!-- Recents: The relative range of visible tasks from the current scroll position
          while the stack is focused. -->
-    <item name="recents_layout_focused_range_min" format="float" type="integer">-4</item>
+    <item name="recents_layout_focused_range_min" format="float" type="integer">-3</item>
     <item name="recents_layout_focused_range_max" format="float" type="integer">3</item>
 
     <!-- Recents: The relative range of visible tasks from the current scroll position
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index 98f8d95..6efa264 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"அறிவிப்புகள்\nவேண்டாம்"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"முன்னுரிமைகள்\nமட்டும்"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"அலாரங்கள்\nமட்டும்"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"எல்லாம்"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"முகப்பு"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"சமீபத்தியவை"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"முந்தையது"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings_tv.xml b/packages/SystemUI/res/values-ta-rIN/strings_tv.xml
new file mode 100644
index 0000000..3f15396
--- /dev/null
+++ b/packages/SystemUI/res/values-ta-rIN/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"PIPஐ மூடு"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"முழுத்திரை"</string>
+    <string name="pip_play" msgid="674145557658227044">"இயக்கு"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"இடைநிறுத்து"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"ரத்துசெய்"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"PIPஐக் கட்டுப்படுத்த, முகப்பைப் பிடித்திருக்கவும்"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml
index 32df57f..2d30739 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -331,6 +331,8 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"మొత్తం\nనిశ్శబ్దం"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ప్రాధాన్యమైనవి\nమాత్రమే"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"అలారాలు\nమాత్రమే"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"అన్నిటికీ"</string>
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"అన్నీ\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>
@@ -480,4 +482,9 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"హోమ్"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ఇటీవలివి"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"వెనుకకు"</string>
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"వాల్యూమ్‌లో అంతరాయం కలిగించవద్దు ప్యానెల్‌ను చూపు"</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"వాల్యూమ్‌ డైలాగ్‌లో అంతరాయం కలిగించవద్దు ప్యానెల్ పూర్తి నియంత్రణను అనుమతిస్తుంది."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"వాల్యూమ్ మరియు అంతరాయం కలిగించవద్దు"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"వాల్యూమ్ తగ్గిస్తే అంతరాయం కలిగించవద్దులోకి ప్రవేశిస్తుంది"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"వాల్యూమ్ పెంచితే అంతరాయం కలిగించవద్దు నుండి నిష్క్రమిస్తుంది"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-te-rIN/strings_tv.xml b/packages/SystemUI/res/values-te-rIN/strings_tv.xml
new file mode 100644
index 0000000..a3148ddf
--- /dev/null
+++ b/packages/SystemUI/res/values-te-rIN/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"PIPని మూసివేయి"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"పూర్తి స్క్రీన్"</string>
+    <string name="pip_play" msgid="674145557658227044">"ప్లే చేయి"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"పాజ్ చేయి"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"రద్దు చేయి"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"PIPని నియంత్రించడానికి HOMEని నొక్కి ఉంచండి"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 2541752..9ac8c16 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"ปิดเสียง\nทั้งหมด"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"เฉพาะเรื่อง\nสำคัญ"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"เฉพาะปลุก\nเท่านั้น"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"ทั้งหมด"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"หน้าแรก"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ล่าสุด"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"กลับ"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings_tv.xml b/packages/SystemUI/res/values-th/strings_tv.xml
new file mode 100644
index 0000000..5921a18
--- /dev/null
+++ b/packages/SystemUI/res/values-th/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"ปิด PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"เต็มหน้าจอ"</string>
+    <string name="pip_play" msgid="674145557658227044">"เล่น"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"หยุดชั่วคราว"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"ยกเลิก"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"กดค้างที่ HOME เพื่อควบคุม PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 5c14ed6..1d5a3b4 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Ganap na\nkatahimikan"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Priyoridad\nlang"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Mga alarm\nlang"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Lahat"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Nagtsa-charge (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hanggang mapuno)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Mabilis mag-charge (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hanggang sa mapuno)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Mabagal mag-charge (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hanggang sa mapuno)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Mga Kamakailang Ginamit"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Bumalik"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings_tv.xml b/packages/SystemUI/res/values-tl/strings_tv.xml
new file mode 100644
index 0000000..7940251
--- /dev/null
+++ b/packages/SystemUI/res/values-tl/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"Isara ang PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Full screen"</string>
+    <string name="pip_play" msgid="674145557658227044">"I-play"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"I-pause"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Kanselahin"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"Pindutin nang matagal ang HOME upang kontrolin ang PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 6cd0e5c..22108b5 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Tamamen\nsessiz"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Yalnızca\nöncelik"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Yalnızca\nalarmlar"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Tümü"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Şarj oluyor (tamamen dolmasına <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> kaldı)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Hızlı şarj oluyor (tam dolmasına <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> kaldı)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Yavaş şarj oluyor (tam dolmasına <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> kaldı)"</string>
@@ -477,7 +480,17 @@
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Pil Tasarrufu"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Performansı ve arka plan verilerini azaltır"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
-    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ana skran"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ana ekran"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Son çağrılar"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Geri"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings_tv.xml b/packages/SystemUI/res/values-tr/strings_tv.xml
new file mode 100644
index 0000000..69ed9c8
--- /dev/null
+++ b/packages/SystemUI/res/values-tr/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"PIP\'yi kapat"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"Tam ekran"</string>
+    <string name="pip_play" msgid="674145557658227044">"Oynat"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Duraklat"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"İptal"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"PIP\'yi kontrol etmek için ANA EKRAN düğmesini basılı tutun"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 6577e28..615a4c4 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -333,6 +333,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Без\nсигналів"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Лише\nприорітетні"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Лише\nсигнали"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Усі"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -482,4 +485,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Головний екран"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Останні"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Назад"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index 3ebe3d5..a789eec 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"مکمل\nخاموشی"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"صرف\nترجیحی"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"صرف\nالارمز"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"سبھی"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ہوم"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"حالیہ"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"پیچھے"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings_tv.xml b/packages/SystemUI/res/values-ur-rPK/strings_tv.xml
new file mode 100644
index 0000000..b7af745
--- /dev/null
+++ b/packages/SystemUI/res/values-ur-rPK/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"‏PIP بند کریں"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"فُل اسکرین"</string>
+    <string name="pip_play" msgid="674145557658227044">"چلائیں"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"موقوف کریں"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"منسوخ کریں"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"‏pip کو کنٹرول کرنے کیلئے ہوم دبا کے رکھیں"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index a3eff10..4f32c34 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Tinchlik\nsaqlansin"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Faqat\nmuhimlar"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Faqat\nsignallar"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Barchasi"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Quvvat olmoqda (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>da to‘ladi)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Tez quvvat olmoqda (to‘lishiga <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> qoldi)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Sekin quvvat olmoqda (to‘lishiga <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> qoldi)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Bosh ekran"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"So‘nggi ishlatilganlar"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Orqaga"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml b/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml
new file mode 100644
index 0000000..7a1b69c
--- /dev/null
+++ b/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"PIP’ni yopish"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"To‘liq ekran"</string>
+    <string name="pip_play" msgid="674145557658227044">"Ijro"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"Pauza"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"Bekor qilish"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"PIP’ni boshqarish uchun BOSHIGA tugmasini bosing"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 1a8cfc0..8108810 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Hoàn toàn\ntắt tiếng"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Chỉ\nưu tiên"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Chỉ\nbáo thức"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Tất cả"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Đang sạc (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> cho đến khi đầy)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Sạc nhanh (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> cho tới khi đầy)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Sạc chậm (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> cho tới khi đầy)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Màn hình chính"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Gần đây"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Quay lại"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index cc05de0..1829519 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"完全\n静音"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"仅限\n优先打扰"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"仅限\n闹钟"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"全部"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主屏幕"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"最近"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"返回"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings_tv.xml b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml
new file mode 100644
index 0000000..25d3ff0
--- /dev/null
+++ b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"关闭 PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"全屏"</string>
+    <string name="pip_play" msgid="674145557658227044">"播放"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"暂停"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"取消"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"按住主屏幕图标即可控制 PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index b2f7136..5d268e8 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"完全\n靜音"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"僅限\n優先"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"僅限\n鬧鐘"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"全部"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主畫面"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"最近的活動"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"返回"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings_tv.xml b/packages/SystemUI/res/values-zh-rHK/strings_tv.xml
new file mode 100644
index 0000000..1b46b64
--- /dev/null
+++ b/packages/SystemUI/res/values-zh-rHK/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"關閉 PIP"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"全螢幕"</string>
+    <string name="pip_play" msgid="674145557658227044">"播放"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"暫停"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"取消"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"按住主按鈕即可控制 PIP"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 9d6e4d3..676e003 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"完全\n靜音"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"僅允許\n優先通知"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"僅允許\n鬧鐘"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"全部"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <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>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主畫面"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"近期活動"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"返回"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings_tv.xml b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml
new file mode 100644
index 0000000..8a085b0
--- /dev/null
+++ b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pip_exit" msgid="6423523158795119008">"關閉子母畫面"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"全螢幕"</string>
+    <string name="pip_play" msgid="674145557658227044">"播放"</string>
+    <string name="pip_pause" msgid="8412075640017218862">"暫停"</string>
+    <string name="pip_cancel" msgid="5173898361050559462">"取消"</string>
+    <string name="pip_hold_home" msgid="883546189749854120">"按住「主畫面」圖示即可控制子母畫面"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index c65f6a2..94b9081 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -331,6 +331,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Ukuthula\niokuphelele"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Okubalulekile\nkuphela"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Ama-alamu\nkuphela"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Konke"</string>
+    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
+    <skip />
     <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Iyashaja (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ize igcwale)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Iyashaja ngokushesha (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ize igcwale)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Iyashaja kancane (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ize igcwale)"</string>
@@ -480,4 +483,14 @@
     <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ekhaya"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Okwakamuva"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Emuva"</string>
+    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
+    <skip />
+    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
+    <skip />
+    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
+    <skip />
+    <!-- no translation found for volume_down_silent (66962568467719591) -->
+    <skip />
+    <!-- no translation found for volume_up_silent (7141255269783588286) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index e98ec82..7a87314 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -147,6 +147,9 @@
     <!-- The duration for animating the task decorations in after transitioning from an app. -->
     <integer name="recents_task_enter_from_app_duration">200</integer>
 
+    <!-- The duration for animating the task decorations in after transitioning from an app. -->
+    <integer name="recents_task_enter_from_affiliated_app_duration">125</integer>
+
     <!-- The duration for animating the task decorations out before transitioning to an app. -->
     <integer name="recents_task_exit_to_app_duration">125</integer>
 
@@ -194,7 +197,7 @@
 
     <!-- Recents: The relative range of visible tasks from the current scroll position
          while the stack is focused. -->
-    <item name="recents_layout_focused_range_min" format="float" type="integer">-4</item>
+    <item name="recents_layout_focused_range_min" format="float" type="integer">-3</item>
     <item name="recents_layout_focused_range_max" format="float" type="integer">3</item>
 
     <!-- Recents: The relative range of visible tasks from the current scroll position
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 3fb5f18..91ca289 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -134,9 +134,7 @@
     <dimen name="pull_span_min">25dp</dimen>
 
     <dimen name="qs_tile_height">88dp</dimen>
-    <dimen name="qs_new_tile_height">100dp</dimen>
-    <dimen name="qs_quick_actions_height">88dp</dimen>
-    <dimen name="qs_quick_actions_padding">25dp</dimen>
+    <dimen name="qs_tile_margin">16dp</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>
@@ -212,7 +210,7 @@
     <dimen name="recents_task_view_highlight">1dp</dimen>
 
     <!-- The amount to offset when animating into an affiliate group. -->
-    <dimen name="recents_task_view_affiliate_group_enter_offset">64dp</dimen>
+    <dimen name="recents_task_view_affiliate_group_enter_offset">32dp</dimen>
 
     <!-- The height of a task view bar. -->
     <dimen name="recents_task_bar_height">56dp</dimen>
diff --git a/packages/SystemUI/res/values/dimens_car.xml b/packages/SystemUI/res/values/dimens_car.xml
new file mode 100644
index 0000000..ecdccee
--- /dev/null
+++ b/packages/SystemUI/res/values/dimens_car.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+-->
+<resources>
+    <dimen name="car_lockscreen_disclaimer_title_size">48sp</dimen>
+    <dimen name="car_lockscreen_disclaimer_title_padding_start">96dp</dimen>
+    <dimen name="car_lockscreen_disclaimer_title_padding_top">96dp</dimen>
+    <dimen name="car_lockscreen_disclaimer_text_size">28sp</dimen>
+    <dimen name="car_lockscreen_disclaimer_text_padding_start">96dp</dimen>
+    <dimen name="car_lockscreen_disclaimer_text_padding_end">96dp</dimen>
+    <dimen name="car_lockscreen_disclaimer_text_padding_top">32dp</dimen>
+    <dimen name="car_lockscreen_user_grid_view_padding_start">10dp</dimen>
+    <dimen name="car_lockscreen_user_grid_view_padding_end">10dp</dimen>
+    <dimen name="car_lockscreen_user_grid_view_padding_top">128dp</dimen>
+    <dimen name="car_fullscreen_user_pod_image_avatar_width">128dp</dimen>
+    <dimen name="car_fullscreen_user_pod_image_avatar_height">128dp</dimen>
+    <dimen name="car_fullscreen_user_pod_text_size">24sp</dimen>
+</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index c39ea57..814e7ea 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1315,4 +1315,22 @@
     <!-- SysUI Tuner: Switch to control volume up behavior [CHAR LIMIT=60] -->
     <string name="volume_up_silent">Exit do not disturb on volume up</string>
 
+    <!-- Name of the battery icon in status bar [CHAR LIMIT=30] -->
+    <string name="battery">Battery</string>
+
+    <!-- Name of the clock in status bar [CHAR LIMIT=30] -->
+    <string name="clock">Clock</string>
+
+    <!-- Name of the headset in status bar [CHAR LIMIT=30] -->
+    <string name="headset">Headset</string>
+
+    <!-- Accessibility description of headphones icon [CHAR LIMIT=NONE] -->
+    <string name="accessibility_status_bar_headphones">Headphones connected</string>
+
+    <!-- Accessibility description of headset icon [CHAR LIMIT=NONE] -->
+    <string name="accessibility_status_bar_headset">Headset connected</string>
+
+    <!-- Explanation of the status bar section of the tuner [CHAR LIMIT=NONE] -->
+    <string name="tuner_status_bar_explanation">Enable or disable icons from being shown in the status bar.</string>
+
 </resources>
diff --git a/packages/SystemUI/res/values/strings_car.xml b/packages/SystemUI/res/values/strings_car.xml
new file mode 100644
index 0000000..882773a
--- /dev/null
+++ b/packages/SystemUI/res/values/strings_car.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources>
+    <string name="car_lockscreen_disclaimer_title">Drive safely</string>
+    <string name="car_lockscreen_disclaimer_text">
+        Stay fully aware of driving conditions and always obey applicable laws. Directions may be
+        inaccurate, incomplete, dangerous, not suitable, prohibited, or involve crossing
+        administrative areas. Business information may also be inaccurate or incomplete. Data is
+        not real-time, and location accuracy cannot be guaranteed. Do not handle your mobile device
+        or use apps not intended for Android Auto while driving.
+    </string>
+
+</resources>
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index 483f367..9193754 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -27,6 +27,26 @@
         android:key="status_bar"
         android:title="@string/status_bar" >
 
+        <Preference
+            android:selectable="false"
+            android:summary="@string/tuner_status_bar_explanation" />
+
+        <com.android.systemui.tuner.StatusBarSwitch
+            android:key="rotate"
+            android:title="@string/status_bar_settings_auto_rotation" />
+
+        <com.android.systemui.tuner.StatusBarSwitch
+            android:key="headset"
+            android:title="@string/headset" />
+
+        <com.android.systemui.tuner.StatusBarSwitch
+            android:key="managed_profile"
+            android:title="@string/status_bar_work" />
+
+        <!-- ime -->
+        <!-- sync_failing -->
+        <!-- sync_active -->
+
         <com.android.systemui.tuner.StatusBarSwitch
             android:key="cast"
             android:title="@string/quick_settings_cast_title" />
@@ -39,17 +59,19 @@
             android:key="bluetooth"
             android:title="@string/quick_settings_bluetooth_label" />
 
+        <!-- nfc -->
+        <!-- tty -->
+        <!-- speakerphone -->
+
         <com.android.systemui.tuner.StatusBarSwitch
             android:key="zen"
             android:title="@string/quick_settings_dnd_label" />
 
-        <com.android.systemui.tuner.StatusBarSwitch
-            android:key="alarm_clock"
-            android:title="@string/status_bar_alarm" />
+        <!-- mute -->
 
         <com.android.systemui.tuner.StatusBarSwitch
-            android:key="managed_profile"
-            android:title="@string/status_bar_work" />
+            android:key="volume"
+            android:title="@*android:string/volume_unknown" />
 
         <com.android.systemui.tuner.StatusBarSwitch
             android:key="wifi"
@@ -67,6 +89,22 @@
             android:key="airplane"
             android:title="@string/status_bar_airplane" />
 
+        <!-- other weird signal stuff -->
+
+        <com.android.systemui.tuner.StatusBarSwitch
+            android:key="battery"
+            android:title="@string/battery" />
+
+        <com.android.systemui.tuner.StatusBarSwitch
+            android:key="alarm_clock"
+            android:title="@string/status_bar_alarm" />
+
+        <!-- secure -->
+
+        <com.android.systemui.tuner.StatusBarSwitch
+            android:key="clock"
+            android:title="@string/clock" />
+
     </PreferenceScreen>
 
 
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index cdbdc22..b4f63eb 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -18,13 +18,19 @@
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.os.Handler;
+import android.util.ArraySet;
 import android.util.AttributeSet;
+import android.view.View;
 import android.widget.ImageView;
+import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.tuner.TunerService;
 
-public class BatteryMeterView extends ImageView implements BatteryController.BatteryStateChangeCallback {
+public class BatteryMeterView extends ImageView implements
+        BatteryController.BatteryStateChangeCallback, TunerService.Tunable {
 
     private final BatteryMeterDrawable mDrawable;
+    private final String mSlotBattery;
     private BatteryController mBatteryController;
 
     public BatteryMeterView(Context context) {
@@ -45,6 +51,8 @@
         mDrawable = new BatteryMeterDrawable(context, new Handler(), frameColor);
         atts.recycle();
 
+        mSlotBattery = context.getString(
+                com.android.internal.R.string.status_bar_battery);
         setImageDrawable(mDrawable);
     }
 
@@ -54,10 +62,19 @@
     }
 
     @Override
+    public void onTuningChanged(String key, String newValue) {
+        if (StatusBarIconController.ICON_BLACKLIST.equals(key)) {
+            ArraySet<String> icons = StatusBarIconController.getIconBlacklist(newValue);
+            setVisibility(icons.contains(mSlotBattery) ? View.GONE : View.VISIBLE);
+        }
+    }
+
+    @Override
     public void onAttachedToWindow() {
         super.onAttachedToWindow();
         mBatteryController.addStateChangedCallback(this);
         mDrawable.startListening();
+        TunerService.get(getContext()).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
     }
 
     @Override
@@ -65,6 +82,7 @@
         super.onDetachedFromWindow();
         mBatteryController.removeStateChangedCallback(this);
         mDrawable.stopListening();
+        TunerService.get(getContext()).removeTunable(this);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index d28da41..fd4161f 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -367,6 +367,7 @@
         }
         anim.addListener(new AnimatorListenerAdapter() {
             public void onAnimationEnd(Animator animation) {
+                updateSwipeProgressFromOffset(animView, canAnimViewBeDismissed);
                 mCallback.onChildDismissed(view);
                 if (endAction != null) {
                     endAction.run();
@@ -381,9 +382,17 @@
                 updateSwipeProgressFromOffset(animView, canAnimViewBeDismissed);
             }
         });
+        prepareDismissAnimation(animView, anim);
         anim.start();
     }
 
+    /**
+     * Called to update the dismiss animation.
+     */
+    protected void prepareDismissAnimation(View view, Animator anim) {
+        // Do nothing
+    }
+
     public void snapChild(final View view, float velocity) {
         final View animView = mCallback.getChildContentView(view);
         final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(animView);
@@ -401,14 +410,14 @@
                 mCallback.onChildSnappedBack(animView);
             }
         });
-        updateSnapBackAnimation(anim);
+        prepareSnapBackAnimation(animView, anim);
         anim.start();
     }
 
     /**
      * Called to update the snap back animation.
      */
-    protected void updateSnapBackAnimation(Animator anim) {
+    protected void prepareSnapBackAnimation(View view, Animator anim) {
         // Do nothing
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index ca4a03a..6bc8b50 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -6,8 +6,6 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.LinearLayout;
-
 import com.android.internal.widget.PagerAdapter;
 import com.android.internal.widget.ViewPager;
 import com.android.systemui.R;
@@ -25,7 +23,6 @@
     private final ArrayList<TileRecord> mTiles = new ArrayList<TileRecord>();
     private final ArrayList<TilePage> mPages = new ArrayList<TilePage>();
 
-    private FirstPage mFirstPage;
     private PageIndicator mPageIndicator;
 
     private int mNumPages;
@@ -59,38 +56,38 @@
         mPageIndicator = (PageIndicator) findViewById(R.id.page_indicator);
         ((LayoutParams) mPageIndicator.getLayoutParams()).isDecor = true;
 
-        mFirstPage = (FirstPage) findViewById(R.id.first_page);
-        removeView(mFirstPage); // We don't actually want this on the view yet, just inflated.
-        mPages.add(mFirstPage.mTilePage);
+        mPages.add((TilePage) LayoutInflater.from(mContext)
+                .inflate(R.layout.qs_paged_page, this, false));
     }
 
     @Override
     public int getOffsetTop(TileRecord tile) {
-        if (tile.tileView.getParent() == mFirstPage.mTilePage) {
-            return mFirstPage.getTop() + mFirstPage.mTilePage.getTop();
-        }
-        return ((ViewGroup) tile.tileView.getParent()).getTop();
+        return ((ViewGroup) tile.tileView.getParent()).getTop() + getTop();
     }
 
     @Override
     public void addTile(TileRecord tile) {
         mTiles.add(tile);
-        distributeTiles();
+        postDistributeTiles();
     }
 
     @Override
     public void removeTile(TileRecord tile) {
         if (mTiles.remove(tile)) {
-            distributeTiles();
+            postDistributeTiles();
         }
     }
 
+    private void postDistributeTiles() {
+        removeCallbacks(mDistribute);
+        post(mDistribute);
+    }
+
     private void distributeTiles() {
         if (DEBUG) Log.d(TAG, "Distributing tiles");
-        mFirstPage.mQuickQuickTiles.removeAllViews();
         final int NP = mPages.size();
         for (int i = 0; i < NP; i++) {
-            mPages.get(i).clear();
+            mPages.get(i).removeAllViews();
         }
         int index = 0;
         final int NT = mTiles.size();
@@ -115,10 +112,15 @@
     }
 
     @Override
-    public void updateResources() {
+    public boolean updateResources() {
+        boolean changed = false;
         for (int i = 0; i < mPages.size(); i++) {
-            mPages.get(i).updateResources();
+            changed |= mPages.get(i).updateResources();
         }
+        if (changed) {
+            distributeTiles();
+        }
+        return changed;
     }
 
     @Override
@@ -137,32 +139,12 @@
         setMeasuredDimension(getMeasuredWidth(), maxHeight + mPageIndicator.getMeasuredHeight());
     }
 
-    public static class FirstPage extends LinearLayout {
-        private LinearLayout mQuickQuickTiles;
-        private TilePage mTilePage;
-
-        public FirstPage(Context context, AttributeSet attrs) {
-            super(context, attrs);
-        }
-
+    private final Runnable mDistribute = new Runnable() {
         @Override
-        protected void onFinishInflate() {
-            super.onFinishInflate();
-            mQuickQuickTiles = (LinearLayout) findViewById(R.id.quick_tile_layout);
-            mQuickQuickTiles.setVisibility(View.GONE);
-            mTilePage = (TilePage) findViewById(R.id.tile_page);
-            // Less rows on first page, because it needs room for the quick tiles.
-            mTilePage.mMaxRows = 3;
+        public void run() {
+            distributeTiles();
         }
-
-        @Override
-        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-            // The ViewPager will try to make us taller, don't do it unless we need to.
-            heightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec),
-                    MeasureSpec.AT_MOST);
-            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        }
-    }
+    };
 
     public static class TilePage extends TileLayout {
         private int mMaxRows = 3;
@@ -172,21 +154,19 @@
             updateResources();
         }
 
+        @Override
+        public boolean updateResources() {
+            if (super.updateResources()) {
+                mMaxRows = mColumns != 3 ? 2 : 3;
+                return true;
+            }
+            return false;
+        }
+
         public void setMaxRows(int maxRows) {
             mMaxRows = maxRows;
         }
 
-        @Override
-        protected int getCellHeight() {
-            return mContext.getResources().getDimensionPixelSize(R.dimen.qs_new_tile_height);
-        }
-
-        private void clear() {
-            if (DEBUG) Log.d(TAG, "Clearing page");
-            removeAllViews();
-            mRecords.clear();
-        }
-
         public boolean isFull() {
             return mRecords.size() >= mColumns * mMaxRows;
         }
@@ -201,7 +181,7 @@
 
         public Object instantiateItem(ViewGroup container, int position) {
             if (DEBUG) Log.d(TAG, "Instantiating " + position);
-            ViewGroup view = position == 0 ? mFirstPage : mPages.get(position);
+            ViewGroup view = mPages.get(position);
             container.addView(view);
             return view;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index fd07e50..b5f146b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -557,8 +557,6 @@
     public static final class TileRecord extends Record {
         public QSTile<?> tile;
         public QSTileBaseView tileView;
-        public int row;
-        public int col;
         public boolean scanState;
         public boolean openingDetail;
     }
@@ -607,6 +605,6 @@
         void addTile(TileRecord tile);
         void removeTile(TileRecord tile);
         int getOffsetTop(TileRecord tile);
-        void updateResources();
+        boolean updateResources();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index 56364e9..72629a3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -129,6 +129,10 @@
         mHandler.obtainMessage(H.ADD_CALLBACK, callback).sendToTarget();
     }
 
+    public void removeCallbacks() {
+        mHandler.sendEmptyMessage(H.REMOVE_CALLBACKS);
+    }
+
     public void click() {
         mHandler.sendEmptyMessage(H.CLICK);
     }
@@ -188,6 +192,10 @@
         handleRefreshState(null);
     }
 
+    private void handleRemoveCallbacks() {
+        mCallbacks.clear();
+    }
+
     protected void handleSecondaryClick() {
         // Default to normal click.
         handleClick();
@@ -285,6 +293,7 @@
         private static final int SCAN_STATE_CHANGED = 9;
         private static final int DESTROY = 10;
         private static final int CLEAR_STATE = 11;
+        private static final int REMOVE_CALLBACKS = 12;
 
         private H(Looper looper) {
             super(looper);
@@ -296,7 +305,10 @@
             try {
                 if (msg.what == ADD_CALLBACK) {
                     name = "handleAddCallback";
-                    handleAddCallback((QSTile.Callback)msg.obj);
+                    handleAddCallback((QSTile.Callback) msg.obj);
+                } else if (msg.what == REMOVE_CALLBACKS) {
+                    name = "handleRemoveCallbacks";
+                    handleRemoveCallbacks();
                 } else if (msg.what == CLICK) {
                     name = "handleClick";
                     if (mState.disabledByPolicy) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 5782800..b391c1e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -145,8 +145,9 @@
         }
 
         @Override
-        public void updateResources() {
+        public boolean updateResources() {
             // No resources here.
+            return false;
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index ff11177..59a394f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -5,7 +5,6 @@
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
-
 import com.android.systemui.R;
 import com.android.systemui.qs.QSPanel.QSTileLayout;
 import com.android.systemui.qs.QSPanel.TileRecord;
@@ -21,6 +20,7 @@
     protected int mColumns;
     private int mCellWidth;
     private int mCellHeight;
+    private int mCellMargin;
 
     protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
 
@@ -54,52 +54,33 @@
         super.removeAllViews();
     }
 
-    public void updateResources() {
+    public boolean 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);
+        mCellHeight = mContext.getResources().getDimensionPixelSize(R.dimen.qs_tile_height);
+        mCellMargin = res.getDimensionPixelSize(R.dimen.qs_tile_margin);
         if (mColumns != columns) {
             mColumns = columns;
             postInvalidate();
+            return true;
         }
-    }
-
-    protected int getCellHeight() {
-        return mContext.getResources().getDimensionPixelSize(R.dimen.qs_tile_height);
+        return false;
     }
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        final int numTiles = mRecords.size();
         final int width = MeasureSpec.getSize(widthMeasureSpec);
-        int r = -1;
-        int c = -1;
-        int rows = 0;
-        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)) {
-                r++;
-                c = 0;
-            } else {
-                c++;
-            }
-            record.row = r;
-            record.col = c;
-            rows = r + 1;
-        }
+        final int rows = (numTiles + mColumns - 1) / mColumns;
+        mCellWidth = (width - (mCellMargin * (mColumns + 1))) / mColumns;
 
         View previousView = this;
         for (TileRecord record : mRecords) {
             if (record.tileView.getVisibility() == GONE) continue;
-            final int cw = mCellWidth;
-            final int ch = mCellHeight;
-            record.tileView.measure(exactly(cw), exactly(ch));
+            record.tileView.measure(exactly(mCellWidth), exactly(mCellHeight));
             previousView = record.tileView.updateAccessibilityOrder(previousView);
         }
-        int h = rows == 0 ? 0 : getRowTop(rows);
-        setMeasuredDimension(width, h);
+        setMeasuredDimension(width, (mCellHeight + mCellMargin) * rows + mCellMargin);
     }
 
     private static int exactly(int size) {
@@ -110,37 +91,32 @@
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         final int w = getWidth();
         boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
-        for (TileRecord record : mRecords) {
-            if (record.tileView.getVisibility() == GONE) continue;
-            final int cols = getColumnCount(record.row);
-            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);
+        int row = 0;
+        int column = 0;
+        for (int i = 0; i < mRecords.size(); i++, column++) {
+            if (column == mColumns) {
+                row++;
+                column -= mColumns;
+            }
+            TileRecord record = mRecords.get(i);
+            int left = getColumnStart(column);
+            final int top = getRowTop(row);
             int right;
-            int tileWith = record.tileView.getMeasuredWidth();
             if (isRtl) {
                 right = w - left;
-                left = right - tileWith;
+                left = right - mCellWidth;
             } else {
-                right = left + tileWith;
+                right = left + mCellWidth;
             }
             record.tileView.layout(left, top, right, top + record.tileView.getMeasuredHeight());
         }
     }
 
     private int getRowTop(int row) {
-        if (row <= 0) return 0;
-        return row * mCellHeight;
+        return row * (mCellHeight + mCellMargin) + mCellMargin;
     }
 
-    private int getColumnCount(int row) {
-        int cols = 0;
-        for (TileRecord record : mRecords) {
-            if (record.tileView.getVisibility() == GONE) continue;
-            if (record.row == row) cols++;
-        }
-        return cols;
+    private int getColumnStart(int column) {
+        return column * (mCellWidth + mCellMargin) + mCellMargin;
     }
-
 }
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 3acbed8..8f0d194 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/NonPagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/NonPagedTileLayout.java
@@ -31,7 +31,6 @@
 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.QuickTileLayout;
 
 import java.util.ArrayList;
 
@@ -42,7 +41,6 @@
  */
 public class NonPagedTileLayout extends LinearLayout implements QSTileLayout, OnTouchListener {
 
-    private QuickTileLayout mQuickTiles;
     private final ArrayList<TilePage> mPages = new ArrayList<>();
     private final ArrayList<TileRecord> mTiles = new ArrayList<TileRecord>();
     private CustomQSPanel mPanel;
@@ -58,8 +56,6 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mQuickTiles = (QuickTileLayout) findViewById(R.id.quick_tile_layout);
-        mQuickTiles.setVisibility(View.GONE);
         TilePage page = (PagedTileLayout.TilePage) findViewById(R.id.tile_page);
         page.setMaxRows(3 /* First page only gets 3 */);
         mPages.add(page);
@@ -95,7 +91,6 @@
     }
 
     private void distributeTiles() {
-        mQuickTiles.removeAllViews();
         final int NP = mPages.size();
         for (int i = 0; i < NP; i++) {
             mPages.get(i).removeAllViews();
@@ -124,7 +119,8 @@
     }
 
     @Override
-    public void updateResources() {
+    public boolean updateResources() {
+        return false;
     }
 
     @Override
@@ -133,24 +129,20 @@
             case DragEvent.ACTION_DRAG_LOCATION:
                 float x = event.getX();
                 float y = event.getY();
-                if (contains(mQuickTiles, x, y)) {
-                    // TODO: Reset to pre-drag state.
-                } else {
-                    final int NP = mPages.size();
-                    for (int i = 0; i < NP; i++) {
-                        TilePage page = mPages.get(i);
-                        if (contains(page, x, y)) {
-                            x -= page.getLeft();
-                            y -= page.getTop();
-                            final int NC = page.getChildCount();
-                            for (int j = 0; j < NC; j++) {
-                                View child = page.getChildAt(j);
-                                if (contains(child, x, y)) {
-                                    mPanel.tileSelected((QSTile<?>) child.getTag(), mCurrentClip);
-                                }
+                final int NP = mPages.size();
+                for (int i = 0; i < NP; i++) {
+                    TilePage page = mPages.get(i);
+                    if (contains(page, x, y)) {
+                        x -= page.getLeft();
+                        y -= page.getTop();
+                        final int NC = page.getChildCount();
+                        for (int j = 0; j < NC; j++) {
+                            View child = page.getChildAt(j);
+                            if (contains(child, x, y)) {
+                                mPanel.tileSelected((QSTile<?>) child.getTag(), mCurrentClip);
                             }
-                            break;
                         }
+                        break;
                     }
                 }
                 break;
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 4a7d67f..cc4ce70 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -45,7 +45,6 @@
 import com.android.systemui.statusbar.phone.PhoneStatusBar;
 import com.android.systemui.statusbar.phone.QSTileHost;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
-import com.android.systemui.tuner.QSPagingSwitch;
 
 import java.util.ArrayList;
 
@@ -145,7 +144,8 @@
 
     private void reset() {
         ArrayList<String> tiles = new ArrayList<>();
-        for (String tile : QSPagingSwitch.QS_PAGE_TILES.split(",")) {
+        String defTiles = mContext.getString(R.string.quick_settings_tiles_default);
+        for (String tile : defTiles.split(",")) {
             tiles.add(tile);
         }
         mQsPanel.setTiles(tiles);
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 a6a7143..6e22dde 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -37,13 +37,11 @@
 import android.widget.GridLayout;
 import android.widget.ImageView;
 import android.widget.TextView;
-
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.qs.QSTile.Icon;
 import com.android.systemui.qs.external.CustomTile;
 import com.android.systemui.statusbar.phone.QSTileHost;
-import com.android.systemui.tuner.QSPagingSwitch;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -74,8 +72,9 @@
             }
             mCurrentTiles = tileSpecs;
             final TileGroup group = new TileGroup("com.android.settings", mContext);
-            // TODO: Pull this list from a more authoritative place.
-            String[] possibleTiles = QSPagingSwitch.QS_PAGE_TILES.split(",");
+            String possible = mContext.getString(R.string.quick_settings_tiles_default)
+                    + ",user,hotspot,inversion";
+            String[] possibleTiles = possible.split(",");
             for (int i = 0; i < possibleTiles.length; i++) {
                 final String spec = possibleTiles[i];
                 if (spec.startsWith("q")) {
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 7bce54b..79155b2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RotationLockTile.java
@@ -16,8 +16,8 @@
 
 package com.android.systemui.qs.tiles;
 
+import android.content.Context;
 import android.content.res.Configuration;
-
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
@@ -78,7 +78,7 @@
             return;
         }
         state.value = rotationLocked;
-        final boolean portrait = isCurrentOrientationLockPortrait();
+        final boolean portrait = isCurrentOrientationLockPortrait(mController, mContext);
         if (rotationLocked) {
             final int label = portrait ? R.string.quick_settings_rotation_locked_portrait_label
                     : R.string.quick_settings_rotation_locked_landscape_label;
@@ -94,11 +94,12 @@
                 R.string.accessibility_rotation_lock_off);
     }
 
-    private boolean isCurrentOrientationLockPortrait() {
-        int lockOrientation = mController.getRotationLockOrientation();
+    public static boolean isCurrentOrientationLockPortrait(RotationLockController controller,
+            Context context) {
+        int lockOrientation = controller.getRotationLockOrientation();
         if (lockOrientation == Configuration.ORIENTATION_UNDEFINED) {
             // Freely rotating device; use current rotation
-            return mContext.getResources().getConfiguration().orientation
+            return context.getResources().getConfiguration().orientation
                     != Configuration.ORIENTATION_LANDSCAPE;
         } else {
             return lockOrientation != Configuration.ORIENTATION_LANDSCAPE;
@@ -123,7 +124,8 @@
             int idWhenOff) {
         int stringID;
         if (locked) {
-            stringID = isCurrentOrientationLockPortrait() ? idWhenPortrait: idWhenLandscape;
+            stringID = isCurrentOrientationLockPortrait(mController, mContext) ? idWhenPortrait
+                    : idWhenLandscape;
         } else {
             stringID = idWhenOff;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index db55f28..3a3b19d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -183,7 +183,7 @@
         RecentsConfiguration config = Recents.getConfiguration();
         RecentsActivityLaunchState launchState = config.getLaunchState();
         if (!plan.hasTasks()) {
-            loader.preloadTasks(plan, launchState.launchedFromHome);
+            loader.preloadTasks(plan, -1, launchState.launchedFromHome);
         }
         RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
         loadOpts.runningTaskId = launchState.launchedToTaskId;
@@ -192,24 +192,14 @@
         loader.loadTasks(this, plan, loadOpts);
 
         TaskStack stack = plan.getTaskStack();
-        ArrayList<Task> tasks = stack.getStackTasks();
-        int taskCount = stack.getTaskCount();
         mRecentsView.setTaskStack(stack);
 
-        // Mark the task that is the launch target
-        int launchTaskIndexInStack = 0;
-        if (launchState.launchedToTaskId != -1) {
-            for (int j = 0; j < taskCount; j++) {
-                Task t = tasks.get(j);
-                if (t.key.id == launchState.launchedToTaskId) {
-                    t.isLaunchTarget = true;
-                    launchTaskIndexInStack = tasks.size() - j - 1;
-                    break;
-                }
-            }
-        }
-
         // Animate the SystemUI scrims into view
+        Task launchTarget = stack.getLaunchTarget();
+        int taskCount = stack.getTaskCount();
+        int launchTaskIndexInStack = launchTarget != null
+                ? stack.indexOfStackTask(launchTarget)
+                : 0;
         boolean hasStatusBarScrim = taskCount > 0;
         boolean animateStatusBarScrim = launchState.launchedFromHome;
         boolean hasNavBarScrim = (taskCount > 0) && !config.hasTransposedNavBar;
@@ -527,7 +517,7 @@
             launchOpts.loadThumbnails = false;
             launchOpts.onlyLoadForCache = true;
             RecentsTaskLoadPlan loadPlan = loader.createLoadPlan(this);
-            loader.preloadTasks(loadPlan, false);
+            loader.preloadTasks(loadPlan, -1, false);
             loader.loadTasks(this, loadPlan, launchOpts);
             EventBus.getDefault().send(new TaskStackUpdatedEvent(loadPlan.getTaskStack()));
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
index 3151fd7..3866967 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
@@ -37,6 +37,8 @@
         public static final boolean EnableSearchBar = false;
         // This disables the bitmap and icon caches
         public static final boolean DisableBackgroundCache = false;
+        // Enables the task affiliations
+        public static final boolean EnableAffiliatedTaskGroups = true;
         // Enables the simulated task affiliations
         public static final boolean EnableSimulatedTaskGroups = false;
         // Defines the number of mock task affiliations per group
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 7c25d24..3eee087 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -118,7 +118,7 @@
 
                 // Load the next task only if we aren't svelte
                 RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
-                loader.preloadTasks(plan, true);
+                loader.preloadTasks(plan, -1, true /* isTopTaskHome */);
                 RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
                 // This callback is made when a new activity is launched and the old one is paused
                 // so ignore the current activity and try and preload the thumbnail for the
@@ -198,7 +198,7 @@
         // We can use a new plan since the caches will be the same.
         RecentsTaskLoader loader = Recents.getTaskLoader();
         RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
-        loader.preloadTasks(plan, true /* isTopTaskHome */);
+        loader.preloadTasks(plan, -1, true /* isTopTaskHome */);
         RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
         launchOpts.numVisibleTasks = loader.getIconCacheSize();
         launchOpts.numVisibleTaskThumbnails = loader.getThumbnailCacheSize();
@@ -370,7 +370,7 @@
         sInstanceLoadPlan = loader.createLoadPlan(mContext);
         if (topTask != null && !ssp.isRecentsTopMost(topTask, topTaskHome)) {
             sInstanceLoadPlan.preloadRawTasks(topTaskHome.value);
-            loader.preloadTasks(sInstanceLoadPlan, topTaskHome.value);
+            loader.preloadTasks(sInstanceLoadPlan, topTask.id, topTaskHome.value);
             TaskStack stack = sInstanceLoadPlan.getTaskStack();
             if (stack.getTaskCount() > 0) {
                 // We try and draw the thumbnail transition bitmap in parallel before
@@ -399,7 +399,7 @@
         SystemServicesProxy ssp = Recents.getSystemServices();
         RecentsTaskLoader loader = Recents.getTaskLoader();
         RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
-        loader.preloadTasks(plan, true /* isTopTaskHome */);
+        loader.preloadTasks(plan, -1, true /* isTopTaskHome */);
         TaskStack focusedStack = plan.getTaskStack();
 
         // Return early if there are no tasks in the focused stack
@@ -451,7 +451,7 @@
         SystemServicesProxy ssp = Recents.getSystemServices();
         RecentsTaskLoader loader = Recents.getTaskLoader();
         RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
-        loader.preloadTasks(plan, true /* isTopTaskHome */);
+        loader.preloadTasks(plan, -1, true /* isTopTaskHome */);
         TaskStack focusedStack = plan.getTaskStack();
 
         // Return early if there are no tasks in the focused stack
@@ -756,29 +756,18 @@
     private TaskViewTransform getThumbnailTransitionTransform(TaskStack stack,
             TaskStackView stackView, int runningTaskId, Task runningTaskOut) {
         // Find the running task in the TaskStack
-        Task task = null;
-        ArrayList<Task> tasks = stack.getStackTasks();
-        if (runningTaskId != -1) {
-            // Otherwise, try and find the task with the
-            int taskCount = tasks.size();
-            for (int i = taskCount - 1; i >= 0; i--) {
-                Task t = tasks.get(i);
-                if (t.key.id == runningTaskId) {
-                    task = t;
-                    runningTaskOut.copyFrom(t);
-                    break;
-                }
-            }
-        }
-        if (task == null) {
+        Task launchTask = stack.getLaunchTarget();
+        if (launchTask != null) {
+            runningTaskOut.copyFrom(launchTask);
+        } else {
             // If no task is specified or we can not find the task just use the front most one
-            task = tasks.get(tasks.size() - 1);
-            runningTaskOut.copyFrom(task);
+            launchTask = stack.getStackFrontMostTask();
+            runningTaskOut.copyFrom(launchTask);
         }
 
         // Get the transform for the running task
         stackView.getScroller().setStackScrollToInitialState();
-        mTmpTransform = stackView.getStackAlgorithm().getStackTransform(task,
+        mTmpTransform = stackView.getStackAlgorithm().getStackTransform(launchTask,
                 stackView.getScroller().getStackScroll(), mTmpTransform, null);
         return mTmpTransform;
     }
@@ -826,7 +815,7 @@
             sInstanceLoadPlan = loader.createLoadPlan(mContext);
         }
         if (mReloadTasks || mTriggeredFromAltTab || !sInstanceLoadPlan.hasTasks()) {
-            loader.preloadTasks(sInstanceLoadPlan, isTopTaskHome);
+            loader.preloadTasks(sInstanceLoadPlan, topTask.id, isTopTaskHome);
         }
         TaskStack stack = sInstanceLoadPlan.getTaskStack();
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java
index 80597bc..f6655c7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java
@@ -36,6 +36,7 @@
 import com.android.systemui.recents.model.RecentsTaskLoader;
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.TaskStack;
+import com.android.systemui.recents.views.TaskViewAnimation;
 
 import java.util.ArrayList;
 import java.util.Calendar;
@@ -143,7 +144,6 @@
 
     private Context mContext;
     private LayoutInflater mLayoutInflater;
-    private final List<Task> mTasks = new ArrayList<>();
     private final List<Row> mRows = new ArrayList<>();
     private final SparseIntArray mTaskRowCount = new SparseIntArray();
     private TaskStack mStack;
@@ -268,8 +268,8 @@
 
     public void onTaskRemoved(Task task, int position) {
         // Since this is removed from the history, we need to update the stack as well to ensure
-        // that the model is correct
-        mStack.removeTask(task);
+        // that the model is correct. Since the stack is hidden, we can update it immediately.
+        mStack.removeTask(task, TaskViewAnimation.IMMEDIATE);
         removeTaskRow(position);
         if (mRows.isEmpty()) {
             dismissHistory();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/RectFEvaluator.java b/packages/SystemUI/src/com/android/systemui/recents/misc/RectFEvaluator.java
new file mode 100644
index 0000000..72511de
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/RectFEvaluator.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.recents.misc;
+
+import android.animation.TypeEvaluator;
+import android.graphics.RectF;
+
+/**
+ * This evaluator can be used to perform type interpolation between <code>RectF</code> values.
+ */
+public class RectFEvaluator implements TypeEvaluator<RectF> {
+
+    private RectF mRect = new RectF();
+
+    /**
+     * This function returns the result of linearly interpolating the start and
+     * end Rect values, with <code>fraction</code> representing the proportion
+     * between the start and end values. The calculation is a simple parametric
+     * calculation on each of the separate components in the Rect objects
+     * (left, top, right, and bottom).
+     *
+     * <p>The object returned will be the <code>reuseRect</code> passed into the constructor.</p>
+     *
+     * @param fraction   The fraction from the starting to the ending values
+     * @param startValue The start Rect
+     * @param endValue   The end Rect
+     * @return A linear interpolation between the start and end values, given the
+     *         <code>fraction</code> parameter.
+     */
+    @Override
+    public RectF evaluate(float fraction, RectF startValue, RectF endValue) {
+        float left = startValue.left + ((endValue.left - startValue.left) * fraction);
+        float top = startValue.top + ((endValue.top - startValue.top) * fraction);
+        float right = startValue.right + ((endValue.right - startValue.right) * fraction);
+        float bottom = startValue.bottom + ((endValue.bottom - startValue.bottom) * fraction);
+        mRect.set(left, top, right, bottom);
+        return mRect;
+    }
+}
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 adc1e92..3f52ae8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -30,6 +30,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
@@ -554,39 +555,41 @@
         }
     }
 
-    /** Returns the activity label */
-    public String getActivityLabel(ActivityInfo info) {
+    /**
+     * Returns the activity label, badging if necessary.
+     */
+    public String getBadgedActivityLabel(ActivityInfo info, int userId) {
         if (mPm == null) return null;
 
         // If we are mocking, then return a mock label
         if (RecentsDebugFlags.Static.EnableSystemServicesProxy) {
-            return "Recent Task";
+            return "Recent Task: " + userId;
         }
 
-        return info.loadLabel(mPm).toString();
+        return getBadgedLabel(info.loadLabel(mPm).toString(), userId);
     }
 
-    /** Returns the application label */
-    public String getApplicationLabel(Intent baseIntent, int userId) {
+    /**
+     * Returns the application label, badging if necessary.
+     */
+    public String getBadgedApplicationLabel(ApplicationInfo appInfo, int userId) {
         if (mPm == null) return null;
 
         // If we are mocking, then return a mock label
         if (RecentsDebugFlags.Static.EnableSystemServicesProxy) {
-            return "Recent Task";
+            return "Recent Task App: " + userId;
         }
 
-        ResolveInfo ri = mPm.resolveActivityAsUser(baseIntent, 0, userId);
-        CharSequence label = (ri != null) ? ri.loadLabel(mPm) : null;
-        return (label != null) ? label.toString() : null;
+        return getBadgedLabel(appInfo.loadLabel(mPm).toString(), userId);
     }
 
-    /** Returns the content description for a given task */
-    public String getContentDescription(Intent baseIntent, int userId, String activityLabel,
-            Resources res) {
-        String applicationLabel = getApplicationLabel(baseIntent, userId);
-        if (applicationLabel == null) {
-            return getBadgedLabel(activityLabel, userId);
-        }
+    /**
+     * Returns the content description for a given task, badging it if necessary.  The content
+     * description joins the app and activity labels.
+     */
+    public String getBadgedContentDescription(ActivityInfo info, int userId, Resources res) {
+        String activityLabel = info.loadLabel(mPm).toString();
+        String applicationLabel = info.applicationInfo.loadLabel(mPm).toString();
         String badgedApplicationLabel = getBadgedLabel(applicationLabel, userId);
         return applicationLabel.equals(activityLabel) ? badgedApplicationLabel
                 : res.getString(R.string.accessibility_recents_task_header,
@@ -610,6 +613,22 @@
     }
 
     /**
+     * Returns the application icon for the ApplicationInfo for a user, badging if
+     * necessary.
+     */
+    public Drawable getBadgedApplicationIcon(ApplicationInfo appInfo, int userId) {
+        if (mPm == null) return null;
+
+        // If we are mocking, then return a mock label
+        if (RecentsDebugFlags.Static.EnableSystemServicesProxy) {
+            return new ColorDrawable(0xFF666666);
+        }
+
+        Drawable icon = appInfo.loadIcon(mPm);
+        return getBadgedIcon(icon, userId);
+    }
+
+    /**
      * Returns the task description icon, loading and badging it if it necessary.
      */
     public Drawable getBadgedTaskDescriptionIcon(ActivityManager.TaskDescription taskDescription,
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 822ad77..9cdd703 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -25,7 +25,8 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.ArraySet;
-
+import android.util.SparseArray;
+import android.util.SparseIntArray;
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
@@ -92,7 +93,7 @@
     }
 
     /**
-     * An optimization to preload the raw list of tasks.  The raw tasks are saved in least-recent
+     * 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) {
@@ -107,7 +108,7 @@
     }
 
     /**
-     * Preloads the list of recent tasks from the system.  After this call, the TaskStack will
+     * Preloads the list of recent tasks from the system. After this call, the TaskStack will
      * have a list of all the recent tasks with their metadata, not including icons or
      * thumbnails which were not cached and have to be loaded.
      *
@@ -115,13 +116,16 @@
      * - least-recent to most-recent stack tasks
      * - least-recent to most-recent freeform tasks
      */
-    public synchronized void preloadPlan(RecentsTaskLoader loader, boolean isTopTaskHome) {
+    public synchronized void preloadPlan(RecentsTaskLoader loader, int topTaskId,
+            boolean isTopTaskHome) {
         Resources res = mContext.getResources();
         ArrayList<Task> allTasks = new ArrayList<>();
         if (mRawTasks == null) {
             preloadRawTasks(isTopTaskHome);
         }
 
+        SparseArray<Task.TaskKey> affiliatedTasks = new SparseArray<>();
+        SparseIntArray affiliatedTaskCounts = new SparseIntArray();
         String dismissDescFormat = mContext.getString(
                 R.string.accessibility_recents_item_will_be_dismissed);
         long lastStackActiveTime = Prefs.getLong(mContext,
@@ -131,6 +135,17 @@
         for (int i = 0; i < taskCount; i++) {
             ActivityManager.RecentTaskInfo t = mRawTasks.get(i);
 
+            // Affiliated tasks are returned in a specific order from ActivityManager but without a
+            // lastActiveTime since it hasn't yet been started. However, we later sort the task list
+            // by lastActiveTime, which rearranges the tasks. For now, we need to workaround this
+            // by updating the lastActiveTime of this task to the lastActiveTime of the task it is
+            // affiliated with, in the same order that we encounter it in the original list (just
+            // its index in the task group for the task it is affiliated with).
+            if (t.persistentId != t.affiliatedTaskId) {
+                t.lastActiveTime = affiliatedTasks.get(t.affiliatedTaskId).lastActiveTime +
+                        affiliatedTaskCounts.get(t.affiliatedTaskId, 0) + 1;
+            }
+
             // Compose the task key
             Task.TaskKey taskKey = new Task.TaskKey(t.persistentId, t.stackId, t.baseIntent,
                     t.userId, t.firstActiveTime, t.lastActiveTime);
@@ -140,13 +155,14 @@
             boolean isFreeformTask = SystemServicesProxy.isFreeformStack(t.stackId);
             boolean isStackTask = isFreeformTask || (!isHistoricalTask(t) ||
                     (t.lastActiveTime >= lastStackActiveTime && i >= (taskCount - MIN_NUM_TASKS)));
+            boolean isLaunchTarget = taskKey.id == topTaskId;
             if (isStackTask && newLastStackActiveTime < 0) {
                 newLastStackActiveTime = t.lastActiveTime;
             }
 
             // Load the title, icon, and color
             String title = loader.getAndUpdateActivityTitle(taskKey, t.taskDescription);
-            String contentDescription = loader.getAndUpdateContentDescription(taskKey, title, res);
+            String contentDescription = loader.getAndUpdateContentDescription(taskKey, res);
             String dismissDescription = String.format(dismissDescFormat, contentDescription);
             Drawable icon = isStackTask
                     ? loader.getAndUpdateActivityIcon(taskKey, t.taskDescription, res, false)
@@ -157,9 +173,11 @@
             // Add the task to the stack
             Task task = new Task(taskKey, t.affiliatedTaskId, t.affiliatedTaskColor, icon,
                     thumbnail, title, contentDescription, dismissDescription, activityColor,
-                    !isStackTask, t.bounds, t.taskDescription);
+                    !isStackTask, isLaunchTarget, t.bounds, t.taskDescription);
 
             allTasks.add(task);
+            affiliatedTaskCounts.put(taskKey.id, affiliatedTaskCounts.get(taskKey.id, 0) + 1);
+            affiliatedTasks.put(taskKey.id, taskKey);
         }
         if (newLastStackActiveTime != -1) {
             Prefs.putLong(mContext, Prefs.Key.OVERVIEW_LAST_STACK_TASK_ACTIVE_TIME,
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
index 28338d83..44ad239 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -314,8 +314,8 @@
     }
 
     /** Preloads recents tasks using the specified plan to store the output. */
-    public void preloadTasks(RecentsTaskLoadPlan plan, boolean isTopTaskHome) {
-        plan.preloadPlan(this, isTopTaskHome);
+    public void preloadTasks(RecentsTaskLoadPlan plan, int topTaskId, boolean isTopTaskHome) {
+        plan.preloadPlan(this, topTaskId, isTopTaskHome);
     }
 
     /** Begins loading the heavy task data according to the specified options. */
@@ -436,7 +436,7 @@
         // All short paths failed, load the label from the activity info and cache it
         ActivityInfo activityInfo = getAndUpdateActivityInfo(taskKey);
         if (activityInfo != null) {
-            label = ssp.getActivityLabel(activityInfo);
+            label = ssp.getBadgedActivityLabel(activityInfo, taskKey.userId);
             mActivityLabelCache.put(taskKey, label);
             return label;
         }
@@ -449,8 +449,7 @@
      * Returns the cached task content description if the task key is not expired, updating the
      * cache if it is.
      */
-    String getAndUpdateContentDescription(Task.TaskKey taskKey, String activityLabel,
-            Resources res) {
+    String getAndUpdateContentDescription(Task.TaskKey taskKey, Resources res) {
         SystemServicesProxy ssp = Recents.getSystemServices();
 
         // Return the cached content description if it exists
@@ -458,13 +457,11 @@
         if (label != null) {
             return label;
         }
-        // If the given activity label is empty, don't compute or cache the content description
-        if (activityLabel.isEmpty()) {
-            return "";
-        }
 
-        label = ssp.getContentDescription(taskKey.baseIntent, taskKey.userId, activityLabel, res);
-        if (label != null) {
+        // All short paths failed, load the label from the activity info and cache it
+        ActivityInfo activityInfo = getAndUpdateActivityInfo(taskKey);
+        if (activityInfo != null) {
+            label = ssp.getBadgedContentDescription(activityInfo, taskKey.userId, res);
             mContentDescriptionCache.put(taskKey, label);
             return label;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
index 29e7077..193bd17 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -154,7 +154,8 @@
     public Task(TaskKey key, int affiliationTaskId, int affiliationColor, Drawable icon,
                 Bitmap thumbnail, String title, String contentDescription,
                 String dismissDescription, int colorPrimary, boolean isHistorical,
-                Rect bounds, ActivityManager.TaskDescription taskDescription) {
+                boolean isLaunchTarget, Rect bounds,
+                ActivityManager.TaskDescription taskDescription) {
         boolean isInAffiliationGroup = (affiliationTaskId != key.id);
         boolean hasAffiliationGroupColor = isInAffiliationGroup && (affiliationColor != 0);
         this.key = key;
@@ -170,6 +171,7 @@
                 Color.WHITE) > 3f;
         this.bounds = bounds;
         this.taskDescription = taskDescription;
+        this.isLaunchTarget = isLaunchTarget;
         this.isHistorical = isHistorical;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
index 327cdf8..c73273e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -42,6 +42,7 @@
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.misc.Utilities;
 import com.android.systemui.recents.views.DropTarget;
+import com.android.systemui.recents.views.TaskViewAnimation;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -226,12 +227,12 @@
          * Notifies when a task has been removed from the stack.
          */
         void onStackTaskRemoved(TaskStack stack, Task removedTask, boolean wasFrontMostTask,
-            Task newFrontMostTask);
+            Task newFrontMostTask, TaskViewAnimation animation);
 
         /**
          * Notifies when a task has been removed from the history.
          */
-        void onHistoryTaskRemoved(TaskStack stack, Task removedTask);
+        void onHistoryTaskRemoved(TaskStack stack, Task removedTask, TaskViewAnimation animation);
     }
 
     /**
@@ -520,21 +521,24 @@
         }
     }
 
-    /** Removes a task */
-    public void removeTask(Task t) {
+    /**
+     * Removes a task from the stack, with an additional {@param animation} hint to the callbacks on
+     * how they should update themselves.
+     */
+    public void removeTask(Task t, TaskViewAnimation animation) {
         if (mStackTaskList.contains(t)) {
             boolean wasFrontMostTask = (getStackFrontMostTask() == t);
             removeTaskImpl(mStackTaskList, t);
             Task newFrontMostTask = getStackFrontMostTask();
             if (mCb != null) {
                 // Notify that a task has been removed
-                mCb.onStackTaskRemoved(this, t, wasFrontMostTask, newFrontMostTask);
+                mCb.onStackTaskRemoved(this, t, wasFrontMostTask, newFrontMostTask, animation);
             }
         } else if (mHistoryTaskList.contains(t)) {
             removeTaskImpl(mHistoryTaskList, t);
             if (mCb != null) {
                 // Notify that a task has been removed
-                mCb.onHistoryTaskRemoved(this, t);
+                mCb.onHistoryTaskRemoved(this, t, animation);
             }
         }
         mRawTaskList.remove(t);
@@ -564,7 +568,8 @@
             Task task = mRawTaskList.get(i);
             if (!newTasksMap.containsKey(task.key)) {
                 if (notifyStackChanges) {
-                    mCb.onStackTaskRemoved(this, task, i == (taskCount - 1), null);
+                    mCb.onStackTaskRemoved(this, task, i == (taskCount - 1), null,
+                            TaskViewAnimation.IMMEDIATE);
                 }
             }
             task.setGroup(null);
@@ -843,12 +848,17 @@
             for (int i = 0; i < taskCount; i++) {
                 Task t = tasks.get(i);
                 TaskGrouping group;
-                int affiliation = t.affiliationTaskId > 0 ? t.affiliationTaskId :
-                        IndividualTaskIdOffset + t.key.id;
-                if (mAffinitiesGroups.containsKey(affiliation)) {
-                    group = getGroupWithAffiliation(affiliation);
+                if (RecentsDebugFlags.Static.EnableAffiliatedTaskGroups) {
+                    int affiliation = t.affiliationTaskId > 0 ? t.affiliationTaskId :
+                            IndividualTaskIdOffset + t.key.id;
+                    if (mAffinitiesGroups.containsKey(affiliation)) {
+                        group = getGroupWithAffiliation(affiliation);
+                    } else {
+                        group = new TaskGrouping(affiliation);
+                        addGroup(group);
+                    }
                 } else {
-                    group = new TaskGrouping(affiliation);
+                    group = new TaskGrouping(t.key.id);
                     addGroup(group);
                 }
                 group.addTask(t);
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 e727652..e448101 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -513,7 +513,7 @@
                     taskViewRect.right, taskViewRect.bottom);
 
             // Remove the task view after it is docked
-            mTaskStackView.updateLayout(false /* boundScroll */);
+            mTaskStackView.updateLayoutAlgorithm(false /* boundScroll */);
             stackLayout.getStackTransform(event.task, stackScroller.getStackScroll(), tmpTransform,
                     null);
             tmpTransform.alpha = 0;
@@ -529,11 +529,14 @@
                                     ssp.startTaskInDockedMode(getContext(), event.taskView,
                                             event.task.key.id, dockState.createMode);
 
-                                    mTaskStackView.getStack().removeTask(event.task);
+                                    // Animate the stack accordingly
+                                    TaskViewAnimation stackAnim = new TaskViewAnimation(
+                                            TaskStackView.DEFAULT_SYNC_STACK_DURATION,
+                                            mFastOutSlowInInterpolator);
+                                    mTaskStackView.getStack().removeTask(event.task, stackAnim);
                                 }
                             }));
 
-
             MetricsLogger.action(mContext,
                     MetricsLogger.ACTION_WINDOW_DOCK_DRAG_DROP);
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
index 2930f4d..ccbb329 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
@@ -130,6 +130,7 @@
                     // Move the task view slightly lower so we can animate it in
                     RectF bounds = new RectF(mTmpTransform.rect);
                     bounds.offset(0, taskViewAffiliateGroupEnterOffset);
+                    tv.setClipViewInStack(false);
                     tv.setAlpha(0f);
                     tv.setLeftTopRightBottom((int) bounds.left, (int) bounds.top,
                             (int) bounds.right, (int) bounds.bottom);
@@ -165,6 +166,8 @@
 
         int taskViewEnterFromAppDuration = res.getInteger(
                 R.integer.recents_task_enter_from_app_duration);
+        int taskViewEnterFromAffiliatedAppDuration = res.getInteger(
+                R.integer.recents_task_enter_from_affiliated_app_duration);
         int taskViewEnterFromHomeDuration = res.getInteger(
                 R.integer.recents_task_enter_from_home_duration);
         int taskViewEnterFromHomeStaggerDelay = res.getInteger(
@@ -174,7 +177,7 @@
         List<TaskView> taskViews = mStackView.getTaskViews();
         int taskViewCount = taskViews.size();
         for (int i = taskViewCount - 1; i >= 0; i--) {
-            TaskView tv = taskViews.get(i);
+            final TaskView tv = taskViews.get(i);
             Task task = tv.getTask();
             boolean currentTaskOccludesLaunchTarget = false;
             if (launchTargetTask != null) {
@@ -195,8 +198,14 @@
                     // Animate the task up if it was occluding the launch target
                     if (currentTaskOccludesLaunchTarget) {
                         TaskViewAnimation taskAnimation = new TaskViewAnimation(
-                                taskViewEnterFromAppDuration, PhoneStatusBar.ALPHA_IN,
-                                postAnimationTrigger.decrementOnAnimationEnd());
+                                taskViewEnterFromAffiliatedAppDuration, PhoneStatusBar.ALPHA_IN,
+                                new AnimatorListenerAdapter() {
+                                    @Override
+                                    public void onAnimationEnd(Animator animation) {
+                                        postAnimationTrigger.decrement();
+                                        tv.setClipViewInStack(false);
+                                    }
+                                });
                         postAnimationTrigger.increment();
                         mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
                     }
@@ -286,7 +295,7 @@
             } else if (currentTaskOccludesLaunchTarget) {
                 // Animate this task out of view
                 TaskViewAnimation taskAnimation = new TaskViewAnimation(
-                        taskViewExitToAppDuration, mFastOutLinearInInterpolator,
+                        taskViewExitToAppDuration, PhoneStatusBar.ALPHA_OUT,
                         postAnimationTrigger.decrementOnAnimationEnd());
                 postAnimationTrigger.increment();
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
index 68ff63c..e99509c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -373,7 +373,7 @@
      * Computes the minimum and maximum scroll progress values and the progress values for each task
      * in the stack.
      */
-    void update(TaskStack stack, ArraySet<Task> ignoreTasksSet) {
+    void update(TaskStack stack, ArraySet<Task.TaskKey> ignoreTasksSet) {
         SystemServicesProxy ssp = Recents.getSystemServices();
 
         // Clear the progress map
@@ -393,7 +393,7 @@
         ArrayList<Task> stackTasks = new ArrayList<>();
         for (int i = 0; i < tasks.size(); i++) {
             Task task = tasks.get(i);
-            if (ignoreTasksSet.contains(task)) {
+            if (ignoreTasksSet.contains(task.key)) {
                 continue;
             }
             if (task.isFreeformTask()) {
@@ -434,19 +434,25 @@
             mFreeformLayoutAlgorithm.update(freeformTasks, this);
             mInitialScrollP = mMaxScrollP;
         } else {
+            Task launchTask = stack.getLaunchTarget();
+            int launchTaskIndex = launchTask != null
+                    ? stack.indexOfStackTask(launchTask)
+                    : mNumStackTasks - 1;
             if (!ssp.hasFreeformWorkspaceSupport() && mNumStackTasks == 1) {
                 mInitialScrollP = mMinScrollP;
             } else if (getDefaultFocusState() > 0f) {
                 RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
                 if (launchState.launchedFromHome) {
-                    mInitialScrollP = Math.max(mMinScrollP, mNumStackTasks - 1);
+                    mInitialScrollP = Math.max(mMinScrollP, Math.min(mMaxScrollP, launchTaskIndex));
                 } else {
-                    mInitialScrollP = Math.max(mMinScrollP, mNumStackTasks - 2);
+                    mInitialScrollP = Math.max(mMinScrollP, Math.min(mMaxScrollP,
+                            launchTaskIndex - 1));
                 }
             } else {
                 float offsetPct = (float) (mTaskRect.height() / 2) / mStackRect.height();
                 float normX = mUnfocusedCurveInterpolator.getX(offsetPct);
-                mInitialScrollP = (mNumStackTasks - 1) - mUnfocusedRange.getAbsoluteX(normX);
+                mInitialScrollP = Math.max(mMinScrollP, Math.min(mMaxScrollP,
+                        launchTaskIndex - mUnfocusedRange.getAbsoluteX(normX)));
             }
         }
     }
@@ -553,7 +559,8 @@
 
             boolean isFrontMostTaskInGroup = task.group == null || task.group.isFrontMostTask(task);
             if (isFrontMostTaskInGroup) {
-                getStackTransform(taskProgress, mInitialScrollP, tmpTransform, null);
+                getStackTransform(taskProgress, mInitialScrollP, tmpTransform, null,
+                        false /* ignoreSingleTaskCase */);
                 float screenY = tmpTransform.rect.top;
                 boolean hasVisibleThumbnail = (prevScreenY - screenY) > taskBarHeight;
                 if (hasVisibleThumbnail) {
@@ -596,13 +603,21 @@
                 return transformOut;
             }
             return getStackTransform(mTaskIndexMap.get(task.key), stackScroll, transformOut,
-                    frontTransform);
+                    frontTransform, false /* ignoreSingleTaskCase */);
         }
     }
 
-    /** Update/get the transform */
+    /**
+     * Update/get the transform.
+     *
+     * @param ignoreSingleTaskCase When set, will ensure that the transform computed does not take
+     *                             into account the special single-task case.  This is only used
+     *                             internally to ensure that we can calculate the transform for any
+     *                             position in the stack.
+     */
     public TaskViewTransform getStackTransform(float taskProgress, float stackScroll,
-            TaskViewTransform transformOut, TaskViewTransform frontTransform) {
+            TaskViewTransform transformOut, TaskViewTransform frontTransform,
+            boolean ignoreSingleTaskCase) {
         SystemServicesProxy ssp = Recents.getSystemServices();
 
         // Compute the focused and unfocused offset
@@ -632,7 +647,7 @@
         int y;
         float z;
         float relP;
-        if (!ssp.hasFreeformWorkspaceSupport() && mNumStackTasks == 1) {
+        if (!ssp.hasFreeformWorkspaceSupport() && mNumStackTasks == 1 && !ignoreSingleTaskCase) {
             // When there is exactly one task, then decouple the task from the stack and just move
             // in screen space
             p = (mMinScrollP - stackScroll) / mNumStackTasks;
@@ -762,8 +777,8 @@
                 mFocusState * (mFocusedRange.relativeMin - mUnfocusedRange.relativeMin);
         float max = mUnfocusedRange.relativeMax +
                 mFocusState * (mFocusedRange.relativeMax - mUnfocusedRange.relativeMax);
-        getStackTransform(min, 0f, mBackOfStackTransform, null);
-        getStackTransform(max, 0f, mFrontOfStackTransform, null);
+        getStackTransform(min, 0f, mBackOfStackTransform, null, true /* ignoreSingleTaskCase */);
+        getStackTransform(max, 0f, mFrontOfStackTransform, null, true /* ignoreSingleTaskCase */);
         mBackOfStackTransform.visible = true;
         mFrontOfStackTransform.visible = true;
     }
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 7583a19..809d4ee 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -30,6 +30,7 @@
 import android.provider.Settings;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.MutableBoolean;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
@@ -77,7 +78,6 @@
 import com.android.systemui.recents.model.TaskStack;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 
 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
@@ -100,10 +100,12 @@
     private static final float SHOW_HISTORY_BUTTON_SCROLL_THRESHOLD = 0.3f;
     private static final float HIDE_HISTORY_BUTTON_SCROLL_THRESHOLD = 0.3f;
 
-    private static final int DEFAULT_SYNC_STACK_DURATION = 200;
+    public static final int DEFAULT_SYNC_STACK_DURATION = 200;
     private static final int DRAG_SCALE_DURATION = 175;
     private static final float DRAG_SCALE_FACTOR = 1.05f;
 
+    private static final ArraySet<Task.TaskKey> EMPTY_TASK_SET = new ArraySet<>();
+
     TaskStack mStack;
     TaskStackLayoutAlgorithm mLayoutAlgorithm;
     TaskStackViewScroller mStackScroller;
@@ -116,7 +118,8 @@
 
     ArrayList<TaskView> mTaskViews = new ArrayList<>();
     ArrayList<TaskViewTransform> mCurrentTaskTransforms = new ArrayList<>();
-    TaskViewAnimation mDeferredTaskViewUpdateAnimation = null;
+    ArraySet<Task.TaskKey> mIgnoreTasks = new ArraySet<>();
+    TaskViewAnimation mDeferredTaskViewLayoutAnimation = null;
 
     DozeTrigger mUIDozeTrigger;
     Task mFocusedTask;
@@ -137,7 +140,6 @@
     int[] mTmpVisibleRange = new int[2];
     Rect mTmpRect = new Rect();
     ArrayMap<Task.TaskKey, TaskView> mTmpTaskViewMap = new ArrayMap<>();
-    ArraySet<Task> mTmpTaskSet = new ArraySet<>();
     List<TaskView> mTmpTaskViews = new ArrayList<>();
     TaskViewTransform mTmpTransform = new TaskViewTransform();
     LayoutInflater mInflater;
@@ -345,30 +347,82 @@
     }
 
     /**
-     * Gets the stack transforms of a list of tasks, and returns the visible range of tasks.
-     * This call ignores freeform tasks.
+     * Adds a task to the ignored set.
      */
-    private boolean updateStackTransforms(ArrayList<TaskViewTransform> taskTransforms,
-            ArrayList<Task> tasks, float stackScroll,
-            int[] visibleRangeOut, ArraySet<Task> ignoreTasksSet) {
-        int taskTransformCount = taskTransforms.size();
+    void addIgnoreTask(Task task) {
+        mIgnoreTasks.add(task.key);
+    }
+
+    /**
+     * Removes a task from the ignored set.
+     */
+    void removeIgnoreTask(Task task) {
+        mIgnoreTasks.remove(task.key);
+    }
+
+    /**
+     * Returns whether the specified {@param task} is ignored.
+     */
+    boolean isIgnoredTask(Task task) {
+        return mIgnoreTasks.contains(task.key);
+    }
+
+    /**
+     * Computes the task transforms at the current stack scroll for all visible tasks. If a valid
+     * target stack scroll is provided (ie. is different than {@param curStackScroll}), then the
+     * visible range includes all tasks at the target stack scroll. This is useful for ensure that
+     * all views necessary for a transition or animation will be visible at the start.
+     *
+     * This call ignores freeform tasks.
+     *
+     * @param taskTransforms The set of task view transforms to reuse, this list will be sized to
+     *                       match the size of {@param tasks}
+     * @param tasks The set of tasks for which to generate transforms
+     * @param curStackScroll The current stack scroll
+     * @param targetStackScroll The stack scroll that we anticipate we are going to be scrolling to.
+     *                          The range of the union of the visible views at the current and
+     *                          target stack scrolls will be returned.
+     * @param ignoreTasksSet The set of tasks to skip for purposes of calculaing the visible range.
+     *                       Transforms will still be calculated for the ignore tasks.
+     */
+    boolean computeVisibleTaskTransforms(ArrayList<TaskViewTransform> taskTransforms,
+            ArrayList<Task> tasks, float curStackScroll, float targetStackScroll,
+            int[] visibleRangeOut, ArraySet<Task.TaskKey> ignoreTasksSet) {
         int taskCount = tasks.size();
         int frontMostVisibleIndex = -1;
         int backMostVisibleIndex = -1;
+        boolean useTargetStackScroll = Float.compare(curStackScroll, targetStackScroll) != 0;
 
         // We can reuse the task transforms where possible to reduce object allocation
         Utilities.matchTaskListSize(tasks, taskTransforms);
 
         // Update the stack transforms
         TaskViewTransform frontTransform = null;
+        TaskViewTransform frontTransformAtTarget = null;
+        TaskViewTransform transform = null;
+        TaskViewTransform transformAtTarget = null;
         for (int i = taskCount - 1; i >= 0; i--) {
             Task task = tasks.get(i);
-            if (ignoreTasksSet.contains(task)) {
-                continue;
+
+            // Calculate the current and (if necessary) the target transform for the task
+            transform = mLayoutAlgorithm.getStackTransform(task, curStackScroll,
+                    taskTransforms.get(i), frontTransform);
+            if (useTargetStackScroll && !transform.visible) {
+                // If we have a target stack scroll and the task is not currently visible, then we
+                // just update the transform at the new scroll
+                // TODO: Optimize this
+                transformAtTarget = mLayoutAlgorithm.getStackTransform(task,
+                        targetStackScroll, new TaskViewTransform(), frontTransformAtTarget);
+                if (transformAtTarget.visible) {
+                    transform.copyFrom(transformAtTarget);
+                }
             }
 
-            TaskViewTransform transform = mLayoutAlgorithm.getStackTransform(task, stackScroll,
-                    taskTransforms.get(i), frontTransform);
+            // For ignore tasks, only calculate the stack transform and skip the calculation of the
+            // visible stack indices
+            if (ignoreTasksSet.contains(task.key)) {
+                continue;
+            }
 
             // For freeform tasks, only calculate the stack transform and skip the calculation of
             // the visible stack indices
@@ -392,7 +446,9 @@
                     break;
                 }
             }
+
             frontTransform = transform;
+            frontTransformAtTarget = transformAtTarget;
         }
         if (visibleRangeOut != null) {
             visibleRangeOut[0] = frontMostVisibleIndex;
@@ -402,33 +458,48 @@
     }
 
     /**
-     * Updates the children {@link TaskView}s to match the tasks in the current {@link TaskStack}.
-     * This call does not update the {@link TaskView}s to their position in the layout except when
-     * they are initially picked up from the pool, when they will be placed in a suitable initial
-     * position.
+     * Binds the visible {@link TaskView}s at the given target scroll.
+     *
+     * @see #bindVisibleTaskViews(float, ArraySet<Task.TaskKey>)
      */
-    private void bindTaskViewsWithStack(ArraySet<Task> ignoreTasksSet) {
-        final float stackScroll = mStackScroller.getStackScroll();
+    void bindVisibleTaskViews(float targetStackScroll) {
+        bindVisibleTaskViews(targetStackScroll, mIgnoreTasks);
+    }
+
+    /**
+     * Synchronizes the set of children {@link TaskView}s to match the visible set of tasks in the
+     * current {@link TaskStack}. This call does not continue on to update their position to the
+     * computed {@link TaskViewTransform}s of the visible range, but only ensures that they will
+     * be added/removed from the view hierarchy and placed in the correct Z order and initial
+     * position (if not currently on screen).
+     *
+     * @param targetStackScroll If provided, will ensure that the set of visible {@link TaskView}s
+     *                          includes those visible at the current stack scroll, and all at the
+     *                          target stack scroll.
+     * @param ignoreTasksSet The set of tasks to ignore in this rebinding of the visible
+     *                       {@link TaskView}s
+     */
+    void bindVisibleTaskViews(float targetStackScroll, ArraySet<Task.TaskKey> ignoreTasksSet) {
         final int[] visibleStackRange = mTmpVisibleRange;
 
         // Get all the task transforms
         final ArrayList<Task> tasks = mStack.getStackTasks();
-        final boolean isValidVisibleStackRange = updateStackTransforms(mCurrentTaskTransforms,
-                tasks, stackScroll, visibleStackRange, ignoreTasksSet);
+        final boolean isValidVisibleRange = computeVisibleTaskTransforms(mCurrentTaskTransforms,
+                tasks, mStackScroller.getStackScroll(), targetStackScroll, visibleStackRange,
+                ignoreTasksSet);
 
         // Return all the invisible children to the pool
-        final List<TaskView> taskViews = getTaskViews();
-        final int taskViewCount = taskViews.size();
-        int lastFocusedTaskIndex = -1;
         mTmpTaskViewMap.clear();
-        mTmpTaskViewMap.ensureCapacity(tasks.size());
+        List<TaskView> taskViews = getTaskViews();
+        int lastFocusedTaskIndex = -1;
+        int taskViewCount = taskViews.size();
         for (int i = taskViewCount - 1; i >= 0; i--) {
-            final TaskView tv = taskViews.get(i);
-            final Task task = tv.getTask();
-            final int taskIndex = mStack.indexOfStackTask(task);
+            TaskView tv = taskViews.get(i);
+            Task task = tv.getTask();
+            int taskIndex = mStack.indexOfStackTask(task);
 
             // Skip ignored tasks
-            if (ignoreTasksSet.contains(task)) {
+            if (ignoreTasksSet.contains(task.key)) {
                 continue;
             }
 
@@ -445,13 +516,13 @@
         }
 
         // Pick up all the newly visible children
-        int lastVisStackIndex = isValidVisibleStackRange ? visibleStackRange[1] : 0;
-        for (int i = mStack.getTaskCount() - 1; i >= lastVisStackIndex; i--) {
-            final Task task = tasks.get(i);
-            final TaskViewTransform transform = mCurrentTaskTransforms.get(i);
+        int lastVisStackIndex = isValidVisibleRange ? visibleStackRange[1] : 0;
+        for (int i = tasks.size() - 1; i >= lastVisStackIndex; i--) {
+            Task task = tasks.get(i);
+            TaskViewTransform transform = mCurrentTaskTransforms.get(i);
 
             // Skip ignored tasks
-            if (ignoreTasksSet.contains(task)) {
+            if (ignoreTasksSet.contains(task.key)) {
                 continue;
             }
 
@@ -502,26 +573,34 @@
     }
 
     /**
-     * Cancels any existing {@link TaskView} animations, and updates each {@link TaskView} to its
-     * current position as defined by the {@link TaskStackLayoutAlgorithm}.
+     * Relayout the the visible {@link TaskView}s to their current transforms as specified by the
+     * {@link TaskStackLayoutAlgorithm} with the given {@param animation}. This call cancels any
+     * animations that are current running on those task views, and will ensure that the children
+     * {@link TaskView}s will match the set of visible tasks in the stack.
      *
-     * @param ignoreTasks the set of tasks to ignore in the relayout
+     * @see #relayoutTaskViews(TaskViewAnimation, ArraySet<Task.TaskKey>)
      */
-    private void updateTaskViewsToLayout(TaskViewAnimation animation, Task... ignoreTasks) {
-        // Keep track of the ignore tasks
-        ArraySet<Task> ignoreTasksSet = mTmpTaskSet;
-        ignoreTasksSet.clear();
-        ignoreTasksSet.ensureCapacity(ignoreTasks.length);
-        Collections.addAll(ignoreTasksSet, ignoreTasks);
+    void relayoutTaskViews(TaskViewAnimation animation) {
+        relayoutTaskViews(animation, mIgnoreTasks);
+    }
 
+    /**
+     * Relayout the the visible {@link TaskView}s to their current transforms as specified by the
+     * {@link TaskStackLayoutAlgorithm} with the given {@param animation}. This call cancels any
+     * animations that are current running on those task views, and will ensure that the children
+     * {@link TaskView}s will match the set of visible tasks in the stack.
+     *
+     * @param ignoreTasksSet the set of tasks to ignore in the relayout
+     */
+    void relayoutTaskViews(TaskViewAnimation animation, ArraySet<Task.TaskKey> ignoreTasksSet) {
         // If we had a deferred animation, cancel that
-        mDeferredTaskViewUpdateAnimation = null;
+        mDeferredTaskViewLayoutAnimation = null;
 
         // Cancel all task view animations
         cancelAllTaskViewAnimations();
 
-        // Fetch the current set of TaskViews
-        bindTaskViewsWithStack(ignoreTasksSet);
+        // Synchronize the current set of TaskViews
+        bindVisibleTaskViews(mStackScroller.getStackScroll(), ignoreTasksSet);
 
         // Animate them to their final transforms with the given animation
         List<TaskView> taskViews = getTaskViews();
@@ -531,7 +610,7 @@
             final int taskIndex = mStack.indexOfStackTask(tv.getTask());
             final TaskViewTransform transform = mCurrentTaskTransforms.get(taskIndex);
 
-            if (ignoreTasksSet.contains(tv.getTask())) {
+            if (ignoreTasksSet.contains(tv.getTask().key)) {
                 continue;
             }
 
@@ -542,8 +621,8 @@
     /**
      * Posts an update to synchronize the {@link TaskView}s with the stack on the next frame.
      */
-    private void updateTaskViewsToLayoutOnNextFrame(TaskViewAnimation animation) {
-        mDeferredTaskViewUpdateAnimation = animation;
+    void relayoutTaskViewsOnNextFrame(TaskViewAnimation animation) {
+        mDeferredTaskViewLayoutAnimation = animation;
         postInvalidateOnAnimation();
     }
 
@@ -558,13 +637,62 @@
     }
 
     /**
-     * Cancels all {@link TaskView} animations.
+     * Returns the current task transforms of all tasks, falling back to the stack layout if there
+     * is no {@link TaskView} for the task.
      */
-    private void cancelAllTaskViewAnimations() {
+    public void getCurrentTaskTransforms(ArrayList<Task> tasks,
+            ArrayList<TaskViewTransform> transformsOut) {
+        Utilities.matchTaskListSize(tasks, transformsOut);
+        for (int i = tasks.size() - 1; i >= 0; i--) {
+            Task task = tasks.get(i);
+            TaskViewTransform transform = transformsOut.get(i);
+            TaskView tv = getChildViewForTask(task);
+            if (tv != null) {
+                transform.fillIn(tv);
+            } else {
+                mLayoutAlgorithm.getStackTransform(task, mStackScroller.getStackScroll(),
+                        transform, null);
+            }
+            transform.visible = true;
+        }
+    }
+
+    /**
+     * Returns the task transforms for all the tasks in the stack if the stack was at the given
+     * {@param stackScroll}.
+     */
+    public void getLayoutTaskTransforms(float stackScroll, ArrayList<Task> tasks,
+            ArrayList<TaskViewTransform> transformsOut) {
+        Utilities.matchTaskListSize(tasks, transformsOut);
+        for (int i = tasks.size() - 1; i >= 0; i--) {
+            Task task = tasks.get(i);
+            TaskViewTransform transform = transformsOut.get(i);
+            mLayoutAlgorithm.getStackTransform(task, stackScroll, transform, null);
+            transform.visible = true;
+        }
+    }
+
+    /**
+     * Cancels all {@link TaskView} animations.
+     *
+     * @see #cancelAllTaskViewAnimations(ArraySet<Task.TaskKey>)
+     */
+    void cancelAllTaskViewAnimations() {
+        cancelAllTaskViewAnimations(mIgnoreTasks);
+    }
+
+    /**
+     * Cancels all {@link TaskView} animations.
+     *
+     * @param ignoreTasksSet The set of tasks to continue running their animations.
+     */
+    void cancelAllTaskViewAnimations(ArraySet<Task.TaskKey> ignoreTasksSet) {
         List<TaskView> taskViews = getTaskViews();
         for (int i = taskViews.size() - 1; i >= 0; i--) {
             final TaskView tv = taskViews.get(i);
-            tv.cancelTransformAnimation();
+            if (!ignoreTasksSet.contains(tv.getTask().key)) {
+                tv.cancelTransformAnimation();
+            }
         }
     }
 
@@ -577,11 +705,22 @@
         // Update the clip on each task child
         List<TaskView> taskViews = getTaskViews();
         TaskView tmpTv = null;
+        TaskView prevVisibleTv = null;
         int taskViewCount = taskViews.size();
         for (int i = 0; i < taskViewCount; i++) {
             TaskView tv = taskViews.get(i);
             TaskView frontTv = null;
             int clipBottom = 0;
+
+            if (mIgnoreTasks.contains(tv.getTask().key)) {
+                // For each of the ignore tasks, update the translationZ of its TaskView to be
+                // between the translationZ of the tasks immediately underneath it
+                if (prevVisibleTv != null) {
+                    tv.setTranslationZ(Math.max(tv.getTranslationZ(),
+                            prevVisibleTv.getTranslationZ() + 0.1f));
+                }
+            }
+
             if (i < (taskViewCount - 1) && tv.shouldClipViewInStack()) {
                 // Find the next view to clip against
                 for (int j = i + 1; j < taskViewCount; j++) {
@@ -609,33 +748,37 @@
             if (!config.useHardwareLayers) {
                 tv.mThumbnailView.updateThumbnailVisibility(clipBottom - tv.getPaddingBottom());
             }
+            prevVisibleTv = tv;
         }
         mTaskViewsClipDirty = false;
     }
 
     /**
+     * Updates the layout algorithm min and max virtual scroll bounds.
+     *
+     * @see #updateLayoutAlgorithm(boolean, ArraySet<Task.TaskKey>)
+     */
+    void updateLayoutAlgorithm(boolean boundScrollToNewMinMax) {
+        updateLayoutAlgorithm(boundScrollToNewMinMax, mIgnoreTasks);
+    }
+
+    /**
      * Updates the min and max virtual scroll bounds.
      *
-     * @param ignoreTasks the set of tasks to ignore in the relayout
+     * @param ignoreTasksSet the set of tasks to ignore in the relayout
      */
-    void updateLayout(boolean boundScrollToNewMinMax, Task... ignoreTasks) {
-        // Keep track of the ingore tasks
-        ArraySet<Task> ignoreTasksSet = mTmpTaskSet;
-        ignoreTasksSet.clear();
-        ignoreTasksSet.ensureCapacity(ignoreTasks.length);
-        Collections.addAll(ignoreTasksSet, ignoreTasks);
-
+    void updateLayoutAlgorithm(boolean boundScrollToNewMinMax,
+            ArraySet<Task.TaskKey> ignoreTasksSet) {
         // Compute the min and max scroll values
         mLayoutAlgorithm.update(mStack, ignoreTasksSet);
 
-        // Update the freeform workspace
+        // Update the freeform workspace background
         SystemServicesProxy ssp = Recents.getSystemServices();
         if (ssp.hasFreeformWorkspaceSupport()) {
             mTmpRect.set(mLayoutAlgorithm.mFreeformRect);
             mFreeformWorkspaceBackground.setBounds(mTmpRect);
         }
 
-        // Debug logging
         if (boundScrollToNewMinMax) {
             mStackScroller.boundScroll();
         }
@@ -671,8 +814,6 @@
 
         // Reset the last focused task state if changed
         if (mFocusedTask != null) {
-            resetFocusedTask(mFocusedTask);
-
             // Cancel the timer indicator, if applicable
             if (showTimerIndicator) {
                 final TaskView tv = getChildViewForTask(mFocusedTask);
@@ -680,6 +821,8 @@
                     tv.getHeaderView().cancelFocusTimerIndicator();
                 }
             }
+
+            resetFocusedTask(mFocusedTask);
         }
 
         boolean willScroll = false;
@@ -937,10 +1080,10 @@
             // Notify accessibility
             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SCROLLED);
         }
-        if (mDeferredTaskViewUpdateAnimation != null) {
-            updateTaskViewsToLayout(mDeferredTaskViewUpdateAnimation);
+        if (mDeferredTaskViewLayoutAnimation != null) {
+            relayoutTaskViews(mDeferredTaskViewLayoutAnimation);
             mTaskViewsClipDirty = true;
-            mDeferredTaskViewUpdateAnimation = null;
+            mDeferredTaskViewLayoutAnimation = null;
         }
         if (mTaskViewsClipDirty) {
             clipTaskViews();
@@ -948,30 +1091,16 @@
     }
 
     /**
-     * Computes the stack and task rects.
-     *
-     * @param ignoreTasks the set of tasks to ignore in the relayout
-     */
-    public void computeRects(Rect taskStackBounds, boolean boundScroll, Task... ignoreTasks) {
-        // Compute the rects in the stack algorithm
-        mLayoutAlgorithm.initialize(taskStackBounds,
-                TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
-
-        // Update the scroll bounds
-        updateLayout(boundScroll, ignoreTasks);
-    }
-
-    /**
      * This is ONLY used from the Recents component to update the dummy stack view for purposes
      * of getting the task rect to animate to.
      */
     public void updateLayoutForStack(TaskStack stack) {
         mStack = stack;
-        updateLayout(false);
+        updateLayoutAlgorithm(false /* boundScroll */, EMPTY_TASK_SET);
     }
 
     /**
-     * Computes the maximum number of visible tasks and thumbnails.  Requires that
+     * Computes the maximum number of visible tasks and thumbnails. Requires that
      * updateLayoutForStack() is called first.
      */
     public TaskStackLayoutAlgorithm.VisibilityReport computeStackVisibilityReport() {
@@ -1002,16 +1131,18 @@
         int width = MeasureSpec.getSize(widthMeasureSpec);
         int height = MeasureSpec.getSize(heightMeasureSpec);
 
-        // Compute our stack/task rects
-        computeRects(mStackBounds, false);
+        // Compute the rects in the stack algorithm
+        mLayoutAlgorithm.initialize(mStackBounds,
+                TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
+        updateLayoutAlgorithm(false /* boundScroll */, EMPTY_TASK_SET);
 
         // If this is the first layout, then scroll to the front of the stack, then update the
         // TaskViews with the stack so that we can lay them out
         if (mAwaitingFirstLayout) {
             mStackScroller.setStackScrollToInitialState();
         }
-        mTmpTaskSet.clear();
-        bindTaskViewsWithStack(mTmpTaskSet);
+        // Rebind all the views, including the ignore ones
+        bindVisibleTaskViews(mStackScroller.getStackScroll(), EMPTY_TASK_SET);
 
         // Measure each of the TaskViews
         mTmpTaskViews.clear();
@@ -1066,7 +1197,8 @@
                 mStackScroller.boundScroll();
             }
         }
-        updateTaskViewsToLayout(TaskViewAnimation.IMMEDIATE);
+        // Relayout all of the task views including the ignored ones
+        relayoutTaskViews(TaskViewAnimation.IMMEDIATE, EMPTY_TASK_SET);
         clipTaskViews();
 
         if (mAwaitingFirstLayout || !mEnterAnimationComplete) {
@@ -1088,9 +1220,12 @@
 
         // Set the task focused state without requesting view focus, and leave the focus animations
         // until after the enter-animation
+        Task launchTask = mStack.getLaunchTarget();
         RecentsConfiguration config = Recents.getConfiguration();
         RecentsActivityLaunchState launchState = config.getLaunchState();
-        int focusedTaskIndex = launchState.getInitialFocusTaskIndex(mStack.getTaskCount());
+        int focusedTaskIndex = launchTask != null
+                ? mStack.indexOfStackTask(launchTask)
+                : launchState.getInitialFocusTaskIndex(mStack.getTaskCount());
         if (focusedTaskIndex != -1) {
             setFocusedTask(focusedTaskIndex, false /* scrollToTask */,
                     false /* requestViewFocus */);
@@ -1106,8 +1241,29 @@
     }
 
     public boolean isTouchPointInView(float x, float y, TaskView tv) {
-        return (tv.getLeft() <= x && x <= tv.getRight()) &&
-                (tv.getTop() <= y && y <= tv.getBottom());
+        mTmpRect.set(tv.getLeft(), tv.getTop(), tv.getRight(), tv.getBottom());
+        mTmpRect.offset((int) tv.getTranslationX(), (int) tv.getTranslationY());
+        return mTmpRect.contains((int) x, (int) y);
+    }
+
+    /**
+     * Returns a non-ignored task in the {@param tasks} list that can be used as an achor when
+     * calculating the scroll position before and after a layout change.
+     */
+    public Task findAnchorTask(List<Task> tasks, MutableBoolean isFrontMostTask) {
+        for (int i = tasks.size() - 1; i >= 0; i--) {
+            Task task = tasks.get(i);
+
+            // Ignore deleting tasks
+            if (mIgnoreTasks.contains(task.key)) {
+                if (i == tasks.size() - 1) {
+                    isFrontMostTask.value = true;
+                }
+                continue;
+            }
+            return task;
+        }
+        return null;
     }
 
     @Override
@@ -1152,70 +1308,38 @@
     @Override
     public void onStackTaskAdded(TaskStack stack, Task newTask) {
         // Update the min/max scroll and animate other task views into their new positions
-        updateLayout(true);
+        updateLayoutAlgorithm(true /* boundScroll */);
 
         // Animate all the tasks into place
-        updateTaskViewsToLayout(new TaskViewAnimation(DEFAULT_SYNC_STACK_DURATION,
+        relayoutTaskViews(new TaskViewAnimation(DEFAULT_SYNC_STACK_DURATION,
                 mFastOutSlowInInterpolator));
     }
 
+    /**
+     * We expect that the {@link TaskView} associated with the removed task is already hidden.
+     */
     @Override
     public void onStackTaskRemoved(TaskStack stack, Task removedTask, boolean wasFrontMostTask,
-            Task newFrontMostTask) {
+            Task newFrontMostTask, TaskViewAnimation animation) {
         if (mFocusedTask == removedTask) {
             resetFocusedTask(removedTask);
         }
 
-        if (!removedTask.isFreeformTask()) {
-            // Remove the view associated with this task, we can't rely on updateTransforms
-            // to work here because the task is no longer in the list
-            TaskView tv = getChildViewForTask(removedTask);
-            if (tv != null) {
-                mViewPool.returnViewToPool(tv);
-            }
-
-            // Get the stack scroll of the task to anchor to (since we are removing something, the
-            // front most task will be our anchor task)
-            Task anchorTask = mStack.getStackFrontMostTask();
-            float prevAnchorTaskScroll = 0;
-            if (anchorTask != null) {
-                prevAnchorTaskScroll = mLayoutAlgorithm.getStackScrollForTask(anchorTask);
-            }
-
-            // Update the min/max scroll and animate other task views into their new positions
-            updateLayout(true);
-
-            if (wasFrontMostTask) {
-                // Since the max scroll progress is offset from the bottom of the stack, just scroll
-                // to ensure that the new front most task is now fully visible
-                mStackScroller.setStackScroll(mLayoutAlgorithm.mMaxScrollP);
-            } else if (anchorTask != null) {
-                // Otherwise, offset the scroll by the movement of the anchor task
-                float anchorTaskScroll = mLayoutAlgorithm.getStackScrollForTask(anchorTask);
-                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
-                    stackScrollOffset /= 2;
-                }
-                mStackScroller.setStackScroll(mStackScroller.getStackScroll() + stackScrollOffset);
-                mStackScroller.boundScroll();
-            }
-        } else {
-            // Remove the view associated with this task, we can't rely on updateTransforms
-            // to work here because the task is no longer in the list
-            TaskView tv = getChildViewForTask(removedTask);
-            if (tv != null) {
-                mViewPool.returnViewToPool(tv);
-            }
-
-            // Update the min/max scroll and animate other task views into their new positions
-            updateLayout(true);
+        // Remove the view associated with this task, we can't rely on updateTransforms
+        // to work here because the task is no longer in the list
+        TaskView tv = getChildViewForTask(removedTask);
+        if (tv != null) {
+            mViewPool.returnViewToPool(tv);
         }
 
-        // Animate all the tasks into place
-        updateTaskViewsToLayout(new TaskViewAnimation(DEFAULT_SYNC_STACK_DURATION,
-                mFastOutSlowInInterpolator));
+        // Remove the task from the ignored set
+        removeIgnoreTask(removedTask);
+
+        // If requested, relayout with the given animation
+        if (animation != null) {
+            updateLayoutAlgorithm(true /* boundScroll */);
+            relayoutTaskViews(animation);
+        }
 
         // Update the new front most task's action button
         if (mScreenPinningEnabled && newFrontMostTask != null) {
@@ -1232,7 +1356,8 @@
     }
 
     @Override
-    public void onHistoryTaskRemoved(TaskStack stack, Task removedTask) {
+    public void onHistoryTaskRemoved(TaskStack stack, Task removedTask,
+            TaskViewAnimation animation) {
         // To be implemented
     }
 
@@ -1316,7 +1441,10 @@
 
     @Override
     public void onTaskViewClipStateChanged(TaskView tv) {
-        clipTaskViews();
+        if (!mTaskViewsClipDirty) {
+            mTaskViewsClipDirty = true;
+            invalidate();
+        }
     }
 
     /**** TaskStackViewScroller.TaskStackViewScrollerCallbacks ****/
@@ -1324,7 +1452,9 @@
     @Override
     public void onScrollChanged(float prevScroll, float curScroll, TaskViewAnimation animation) {
         mUIDozeTrigger.poke();
-        updateTaskViewsToLayoutOnNextFrame(animation);
+        if (animation != null) {
+            relayoutTaskViewsOnNextFrame(animation);
+        }
 
         if (shouldShowHistoryButton() &&
                 prevScroll > SHOW_HISTORY_BUTTON_SCROLL_THRESHOLD &&
@@ -1354,7 +1484,7 @@
                     tv.dismissTask();
                 } else {
                     // Otherwise, remove the task from the stack immediately
-                    mStack.removeTask(t);
+                    mStack.removeTask(t, TaskViewAnimation.IMMEDIATE);
                 }
             }
         }
@@ -1402,7 +1532,7 @@
     }
 
     public final void onBusEvent(TaskViewDismissedEvent event) {
-        removeTaskViewFromStack(event.taskView);
+        removeTaskViewFromStack(event.taskView, event.task);
         EventBus.getDefault().send(new DeleteTaskDataEvent(event.task));
     }
 
@@ -1419,7 +1549,10 @@
         // Poke the doze trigger on user interaction
         mUIDozeTrigger.poke();
         if (event.showTimerIndicator && mFocusedTask != null) {
-            getChildViewForTask(mFocusedTask).getHeaderView().cancelFocusTimerIndicator();
+            TaskView tv = getChildViewForTask(mFocusedTask);
+            if (tv != null) {
+                tv.getHeaderView().cancelFocusTimerIndicator();
+            }
         }
     }
 
@@ -1455,23 +1588,29 @@
     }
 
     public final void onBusEvent(DragDropTargetChangedEvent event) {
+        TaskViewAnimation animation = new TaskViewAnimation(250, mFastOutSlowInInterpolator);
         if (event.dropTarget instanceof TaskStack.DockState) {
             // Calculate the new task stack bounds that matches the window size that Recents will
             // have after the drop
+            addIgnoreTask(event.task);
             final TaskStack.DockState dockState = (TaskStack.DockState) event.dropTarget;
             mStackBounds.set(dockState.getDockedTaskStackBounds(getMeasuredWidth(),
                     getMeasuredHeight(), mDividerSize, mLayoutAlgorithm.mSystemInsets,
                     getResources()));
-            computeRects(mStackBounds, true /* boundScroll */, event.task /* ignoreTask */);
-            updateTaskViewsToLayout(new TaskViewAnimation(250, mFastOutSlowInInterpolator),
-                    event.task /* ignoreTask */);
+            mLayoutAlgorithm.initialize(mStackBounds,
+                    TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
+            updateLayoutAlgorithm(true /* boundScroll */);
         } else {
-            // Restore the pre-drag task stack bounds
+            // Restore the pre-drag task stack bounds, but ensure that we don't layout the dragging
+            // task view, so add it back to the ignore set after updating the layout
             mStackBounds.set(mStableStackBounds);
-            computeRects(mStackBounds, true /* boundScroll */);
-            updateTaskViewsToLayout(new TaskViewAnimation(250, mFastOutSlowInInterpolator),
-                    event.task /* ignoreTask */);
+            removeIgnoreTask(event.task);
+            mLayoutAlgorithm.initialize(mStackBounds,
+                    TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
+            updateLayoutAlgorithm(true /* boundScroll */);
+            addIgnoreTask(event.task);
         }
+        relayoutTaskViews(animation);
     }
 
     public final void onBusEvent(final DragEndEvent event) {
@@ -1487,14 +1626,14 @@
 
         if (hasChangedStacks) {
             // Move the task to the right position in the stack (ie. the front of the stack if
-            // freeform or the front of the stack if fullscreen).  Note, we MUST move the tasks
+            // freeform or the front of the stack if fullscreen). Note, we MUST move the tasks
             // before we update their stack ids, otherwise, the keys will have changed.
             if (event.dropTarget == mFreeformWorkspaceDropTarget) {
                 mStack.moveTaskToStack(event.task, FREEFORM_WORKSPACE_STACK_ID);
             } else if (event.dropTarget == mStackDropTarget) {
                 mStack.moveTaskToStack(event.task, FULLSCREEN_WORKSPACE_STACK_ID);
             }
-            updateLayout(true);
+            updateLayoutAlgorithm(true /* boundScroll */);
 
             // Move the task to the new stack in the system after the animation completes
             event.addPostAnimationCallback(new Runnable() {
@@ -1522,11 +1661,12 @@
         mLayoutAlgorithm.getStackTransform(event.task, getScroller().getStackScroll(),
                 mTmpTransform, null);
         event.getAnimationTrigger().increment();
-        updateTaskViewsToLayout(new TaskViewAnimation(DEFAULT_SYNC_STACK_DURATION,
+        relayoutTaskViews(new TaskViewAnimation(DEFAULT_SYNC_STACK_DURATION,
                 mFastOutSlowInInterpolator));
         updateTaskViewToTransform(event.taskView, mTmpTransform,
                 new TaskViewAnimation(DEFAULT_SYNC_STACK_DURATION, mFastOutSlowInInterpolator,
                         event.getAnimationTrigger().decrementOnAnimationEnd()));
+        removeIgnoreTask(event.task);
     }
 
     public final void onBusEvent(StackViewScrolledEvent event) {
@@ -1593,15 +1733,14 @@
      * Removes the task from the stack, and updates the focus to the next task in the stack if the
      * removed TaskView was focused.
      */
-    private void removeTaskViewFromStack(TaskView tv) {
-        Task task = tv.getTask();
-
+    private void removeTaskViewFromStack(TaskView tv, Task task) {
         // Announce for accessibility
         tv.announceForAccessibility(getContext().getString(
-                R.string.accessibility_recents_item_dismissed, tv.getTask().title));
+                R.string.accessibility_recents_item_dismissed, task.title));
 
         // Remove the task from the stack
-        mStack.removeTask(task);
+        mStack.removeTask(task, new TaskViewAnimation(DEFAULT_SYNC_STACK_DURATION,
+                mFastOutSlowInInterpolator));
     }
 
     /**
@@ -1622,7 +1761,7 @@
     }
 
     /**
-     * Returns the insert index for the task in the current set of task views.  If the given task
+     * Returns the insert index for the task in the current set of task views. If the given task
      * is already in the task view list, then this method returns the insert index assuming it
      * is first removed at the previous index.
      *
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
index 32f02ac..5335b14 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
@@ -151,6 +151,7 @@
 
     /** Animates the stack scroll into bounds */
     ObjectAnimator animateBoundScroll() {
+        // TODO: Take duration for snap back
         float curScroll = getStackScroll();
         float newScroll = getBoundedStackScroll(curScroll);
         if (Float.compare(newScroll, curScroll) != 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index 4813c19..e9f6f39 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -21,13 +21,16 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Rect;
-import android.util.Log;
+import android.util.ArrayMap;
+import android.util.MutableBoolean;
 import android.view.InputDevice;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewParent;
+import android.view.animation.Interpolator;
+import android.view.animation.PathInterpolator;
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.R;
 import com.android.systemui.SwipeHelper;
@@ -37,19 +40,25 @@
 import com.android.systemui.recents.events.activity.HideRecentsEvent;
 import com.android.systemui.recents.events.ui.StackViewScrolledEvent;
 import com.android.systemui.recents.events.ui.TaskViewDismissedEvent;
+import com.android.systemui.recents.misc.RectFEvaluator;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.misc.Utilities;
+import com.android.systemui.recents.model.Task;
 import com.android.systemui.statusbar.FlingAnimationUtils;
 
+import java.util.ArrayList;
 import java.util.List;
 
-/* Handles touch events for a TaskStackView. */
+/**
+ * Handles touch events for a TaskStackView.
+ */
 class TaskStackViewTouchHandler implements SwipeHelper.Callback {
 
-    private static final String TAG = "TaskStackViewTouchHandler";
-    private static final boolean DEBUG = false;
+    private static final int INACTIVE_POINTER_ID = -1;
 
-    private static int INACTIVE_POINTER_ID = -1;
+    private static final RectFEvaluator RECT_EVALUATOR = new RectFEvaluator();
+    private static final Interpolator STACK_TRANSFORM_INTERPOLATOR =
+            new PathInterpolator(0.73f, 0.33f, 0.42f, 0.85f);
 
     Context mContext;
     TaskStackView mSv;
@@ -74,6 +83,15 @@
     final int mWindowTouchSlop;
 
     private final StackViewScrolledEvent mStackViewScrolledEvent = new StackViewScrolledEvent();
+
+    // The current and final set of task transforms, sized to match the list of tasks in the stack
+    private ArrayList<Task> mCurrentTasks = new ArrayList<>();
+    private ArrayList<TaskViewTransform> mCurrentTaskTransforms = new ArrayList<>();
+    private ArrayList<TaskViewTransform> mFinalTaskTransforms = new ArrayList<>();
+    private ArrayMap<View, Animator> mSwipeHelperAnimations = new ArrayMap<>();
+    private TaskViewTransform mTmpTransform = new TaskViewTransform();
+    private float mTargetStackScroll;
+
     SwipeHelper mSwipeHelper;
     boolean mInterceptedBySwipeHelper;
 
@@ -97,8 +115,14 @@
             }
 
             @Override
-            protected void updateSnapBackAnimation(Animator anim) {
+            protected void prepareDismissAnimation(View v, Animator anim) {
+                mSwipeHelperAnimations.put(v, anim);
+            }
+
+            @Override
+            protected void prepareSnapBackAnimation(View v, Animator anim) {
                 anim.setInterpolator(mSv.mFastOutSlowInInterpolator);
+                mSwipeHelperAnimations.put(v, anim);
             }
         };
         mSwipeHelper.setDisableHardwareLayers(true);
@@ -119,21 +143,6 @@
         }
     }
 
-    /** Returns the view at the specified coordinates */
-    TaskView findViewAtPoint(int x, int y) {
-        List<TaskView> taskViews = mSv.getTaskViews();
-        int taskViewCount = taskViews.size();
-        for (int i = taskViewCount - 1; i >= 0; i--) {
-            TaskView tv = taskViews.get(i);
-            if (tv.getVisibility() == View.VISIBLE) {
-                if (mSv.isTouchPointInView(x, y, tv)) {
-                    return tv;
-                }
-            }
-        }
-        return null;
-    }
-
     /** Touch preprocessing for handling below */
     public boolean onInterceptTouchEvent(MotionEvent ev) {
         // Pass through to swipe helper if we are swiping
@@ -179,6 +188,15 @@
                 mScroller.stopBoundScrollAnimation();
                 Utilities.cancelAnimationWithoutCallbacks(mScrollFlingAnimator);
 
+                // Finish any existing task animations from the delete
+                mSv.cancelAllTaskViewAnimations();
+                // Finish any of the swipe helper animations
+                ArrayMap<View, Animator> existingAnimators = new ArrayMap<>(mSwipeHelperAnimations);
+                for (int i = 0; i < existingAnimators.size(); i++) {
+                    existingAnimators.get(existingAnimators.keyAt(i)).end();
+                }
+                mSwipeHelperAnimations.clear();
+
                 // Initialize the velocity tracker
                 initOrResetVelocityTracker();
                 mVelocityTracker.addMovement(ev);
@@ -214,9 +232,6 @@
                     float deltaP = layoutAlgorithm.getDeltaPForY(mDownY, y);
                     float curScrollP = mDownScrollP + deltaP;
                     mScroller.setStackScroll(curScrollP);
-                    if (DEBUG) {
-                        Log.d(TAG, "scroll: " + curScrollP);
-                    }
                     mStackViewScrolledEvent.updateY(y - mLastY);
                     EventBus.getDefault().send(mStackViewScrolledEvent);
                 }
@@ -343,12 +358,19 @@
 
     @Override
     public View getChildAtPosition(MotionEvent ev) {
-        return findViewAtPoint((int) ev.getX(), (int) ev.getY());
+        TaskView tv = findViewAtPoint((int) ev.getX(), (int) ev.getY());
+        if (tv != null && canChildBeDismissed(tv)) {
+            return tv;
+        }
+        return null;
     }
 
     @Override
     public boolean canChildBeDismissed(View v) {
-        return true;
+        // Disallow dismissing an already dismissed task
+        TaskView tv = (TaskView) v;
+        return !mSwipeHelperAnimations.containsKey(v) &&
+                (mSv.getStack().indexOfStackTask(tv.getTask()) != -1);
     }
 
     @Override
@@ -364,34 +386,113 @@
         if (parent != null) {
             parent.requestDisallowInterceptTouchEvent(true);
         }
+
+        // Add this task to the set of tasks we are deleting
+        mSv.addIgnoreTask(tv.getTask());
+
+        // Determine if we are animating the other tasks while dismissing this task
+        mCurrentTasks = mSv.getStack().getStackTasks();
+        MutableBoolean isFrontMostTask = new MutableBoolean(false);
+        Task anchorTask = mSv.findAnchorTask(mCurrentTasks, isFrontMostTask);
+        TaskStackViewScroller stackScroller = mSv.getScroller();
+        if (anchorTask != null) {
+            // Get the current set of task transforms
+            mSv.getCurrentTaskTransforms(mCurrentTasks, mCurrentTaskTransforms);
+
+            // Get the stack scroll of the task to anchor to (since we are removing something, the
+            // front most task will be our anchor task)
+            float prevAnchorTaskScroll = 0;
+            boolean pullStackForward = mCurrentTasks.size() > 0;
+            if (pullStackForward) {
+                prevAnchorTaskScroll = mSv.getStackAlgorithm().getStackScrollForTask(anchorTask);
+            }
+
+            // Calculate where the views would be without the deleting tasks
+            mSv.updateLayoutAlgorithm(false /* boundScroll */);
+
+            float newStackScroll = stackScroller.getStackScroll();
+            if (isFrontMostTask.value) {
+                // Bound the stack scroll to pull tasks forward if necessary
+                newStackScroll = stackScroller.getBoundedStackScroll(newStackScroll);
+            } else if (pullStackForward) {
+                // Otherwise, offset the scroll by the movement of the anchor task
+                float anchorTaskScroll = mSv.getStackAlgorithm().getStackScrollForTask(anchorTask);
+                float stackScrollOffset = (anchorTaskScroll - prevAnchorTaskScroll);
+                if (mSv.getStackAlgorithm().getFocusState() !=
+                        TaskStackLayoutAlgorithm.STATE_FOCUSED) {
+                    // If we are focused, we don't want the front task to move, but otherwise, we
+                    // allow the back task to move up, and the front task to move back
+                    stackScrollOffset /= 2;
+                }
+                newStackScroll = stackScroller.getBoundedStackScroll(stackScroller.getStackScroll()
+                        + stackScrollOffset);
+            }
+
+            // Pick up the newly visible views, not including the deleting tasks
+            mSv.bindVisibleTaskViews(newStackScroll);
+
+            // Get the final set of task transforms (with task removed)
+            mSv.getLayoutTaskTransforms(newStackScroll, mCurrentTasks, mFinalTaskTransforms);
+
+            // Set the target to scroll towards upon dismissal
+            mTargetStackScroll = newStackScroll;
+
+            /*
+             * Post condition: All views that will be visible as a part of the gesture are retrieved
+             *                 and at their initial positions.  The stack is still at the current
+             *                 scroll, but the layout is updated without the task currently being
+             *                 dismissed.
+             */
+        }
     }
 
     @Override
     public boolean updateSwipeProgress(View v, boolean dismissable, float swipeProgress) {
+        updateTaskViewTransforms(getDismissFraction(v));
         return true;
     }
 
+    /**
+     * Called after the {@link TaskView} is finished animating away.
+     */
     @Override
     public void onChildDismissed(View v) {
         TaskView tv = (TaskView) v;
+
         // Re-enable clipping with the stack (we will reuse this view)
         tv.setClipViewInStack(true);
         // Re-enable touch events from this task view
         tv.setTouchEnabled(true);
+        // Update the scroll to the final scroll position from onBeginDrag()
+        mSv.getScroller().setStackScroll(mTargetStackScroll, null);
         // Remove the task view from the stack
         EventBus.getDefault().send(new TaskViewDismissedEvent(tv.getTask(), tv));
+        // Stop tracking this deletion animation
+        mSwipeHelperAnimations.remove(v);
         // Keep track of deletions by keyboard
         MetricsLogger.histogram(tv.getContext(), "overview_task_dismissed_source",
                 Constants.Metrics.DismissSourceSwipeGesture);
     }
 
+    /**
+     * Called after the {@link TaskView} is finished animating back into the list.
+     * onChildDismissed() calls.
+     */
     @Override
     public void onChildSnappedBack(View v) {
         TaskView tv = (TaskView) v;
+
         // Re-enable clipping with the stack
         tv.setClipViewInStack(true);
         // Re-enable touch events from this task view
         tv.setTouchEnabled(true);
+
+        // Stop tracking this deleting task, and update the layout to include this task again.  The
+        // stack scroll does not need to be reset, since the scroll has not actually changed in
+        // onBeginDrag().
+        mSv.removeIgnoreTask(tv.getTask());
+        mSv.updateLayoutAlgorithm(false /* boundScroll */);
+        mSwipeHelperAnimations.remove(v);
     }
 
     @Override
@@ -414,4 +515,59 @@
         return 0;
     }
 
+    /**
+     * Interpolates the non-deleting tasks to their final transforms from their current transforms.
+     */
+    private void updateTaskViewTransforms(float dismissFraction) {
+        List<TaskView> taskViews = mSv.getTaskViews();
+        int taskViewCount = taskViews.size();
+        for (int i = 0; i < taskViewCount; i++) {
+            TaskView tv = taskViews.get(i);
+            Task task = tv.getTask();
+
+            if (mSv.isIgnoredTask(task)) {
+                continue;
+            }
+
+            int taskIndex = mCurrentTasks.indexOf(task);
+            TaskViewTransform fromTransform = mCurrentTaskTransforms.get(taskIndex);
+            TaskViewTransform toTransform = mFinalTaskTransforms.get(taskIndex);
+
+            mTmpTransform.copyFrom(fromTransform);
+            // We only really need to interpolate the bounds, progress and translation
+            mTmpTransform.rect.set(RECT_EVALUATOR.evaluate(dismissFraction, fromTransform.rect,
+                    toTransform.rect));
+            mTmpTransform.p = fromTransform.p + (toTransform.p - fromTransform.p) * dismissFraction;
+            mTmpTransform.translationZ = fromTransform.translationZ +
+                    (toTransform.translationZ - fromTransform.translationZ) * dismissFraction;
+
+            mSv.updateTaskViewToTransform(tv, mTmpTransform, TaskViewAnimation.IMMEDIATE);
+        }
+    }
+
+    /** Returns the view at the specified coordinates */
+    private TaskView findViewAtPoint(int x, int y) {
+        List<Task> tasks = mSv.getStack().getStackTasks();
+        int taskCount = tasks.size();
+        for (int i = taskCount - 1; i >= 0; i--) {
+            TaskView tv = mSv.getChildViewForTask(tasks.get(i));
+            if (tv != null && tv.getVisibility() == View.VISIBLE) {
+                if (mSv.isTouchPointInView(x, y, tv)) {
+                    return tv;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the fraction which we should interpolate the other task views based on the dismissal
+     * of this given task.
+     *
+     * TODO: We can interpolate this to adjust when the other tasks should respond to the dismissal
+     */
+    private float getDismissFraction(View v) {
+        float fraction = Math.min(1f, Math.abs(v.getTranslationX() / mSv.getWidth()));
+        return STACK_TRANSFORM_INTERPOLATOR.getInterpolation(fraction);
+    }
 }
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 9b72702..1f8216f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -162,6 +162,7 @@
 
     /** Resets this TaskView for reuse. */
     void reset() {
+        mHeaderView.reset();
         resetViewProperties();
         resetNoUserInteractionState();
         setClipViewInStack(false);
@@ -459,16 +460,14 @@
     public void showActionButton(boolean fadeIn, int fadeInDuration) {
         mActionButtonView.setVisibility(View.VISIBLE);
 
-        if (fadeIn) {
-            if (mActionButtonView.getAlpha() < 1f) {
-                mActionButtonView.animate()
-                        .alpha(1f)
-                        .scaleX(1f)
-                        .scaleY(1f)
-                        .setDuration(fadeInDuration)
-                        .setInterpolator(PhoneStatusBar.ALPHA_IN)
-                        .start();
-            }
+        if (fadeIn && mActionButtonView.getAlpha() < 1f) {
+            mActionButtonView.animate()
+                    .alpha(1f)
+                    .scaleX(1f)
+                    .scaleY(1f)
+                    .setDuration(fadeInDuration)
+                    .setInterpolator(PhoneStatusBar.ALPHA_IN)
+                    .start();
         } else {
             mActionButtonView.setScaleX(1f);
             mActionButtonView.setScaleY(1f);
@@ -484,29 +483,27 @@
      */
     public void hideActionButton(boolean fadeOut, int fadeOutDuration, boolean scaleDown,
             final Animator.AnimatorListener animListener) {
-        if (fadeOut) {
-            if (mActionButtonView.getAlpha() > 0f) {
-                if (scaleDown) {
-                    float toScale = 0.9f;
-                    mActionButtonView.animate()
-                            .scaleX(toScale)
-                            .scaleY(toScale);
-                }
+        if (fadeOut && mActionButtonView.getAlpha() > 0f) {
+            if (scaleDown) {
+                float toScale = 0.9f;
                 mActionButtonView.animate()
-                        .alpha(0f)
-                        .setDuration(fadeOutDuration)
-                        .setInterpolator(PhoneStatusBar.ALPHA_OUT)
-                        .withEndAction(new Runnable() {
-                            @Override
-                            public void run() {
-                                if (animListener != null) {
-                                    animListener.onAnimationEnd(null);
-                                }
-                                mActionButtonView.setVisibility(View.INVISIBLE);
-                            }
-                        })
-                        .start();
+                        .scaleX(toScale)
+                        .scaleY(toScale);
             }
+            mActionButtonView.animate()
+                    .alpha(0f)
+                    .setDuration(fadeOutDuration)
+                    .setInterpolator(PhoneStatusBar.ALPHA_OUT)
+                    .withEndAction(new Runnable() {
+                        @Override
+                        public void run() {
+                            if (animListener != null) {
+                                animListener.onAnimationEnd(null);
+                            }
+                            mActionButtonView.setVisibility(View.INVISIBLE);
+                        }
+                    })
+                    .start();
         } else {
             mActionButtonView.setAlpha(0f);
             mActionButtonView.setVisibility(View.INVISIBLE);
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 e7717ac..2563190 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -16,22 +16,27 @@
 
 package com.android.systemui.recents.views;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.annotation.Nullable;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.ActivityInfo;
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.ColorFilter;
 import android.graphics.Paint;
-import android.graphics.PorterDuff;
 import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
-import android.graphics.drawable.RippleDrawable;
-import android.support.v4.graphics.ColorUtils;
 import android.os.CountDownTimer;
+import android.support.v4.graphics.ColorUtils;
 import android.util.AttributeSet;
 import android.view.View;
+import android.view.ViewAnimationUtils;
+import android.view.ViewStub;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.widget.FrameLayout;
@@ -39,10 +44,10 @@
 import android.widget.ProgressBar;
 import android.widget.TextView;
 import com.android.internal.logging.MetricsLogger;
-
 import com.android.systemui.R;
 import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.Recents;
+import com.android.systemui.recents.RecentsDebugFlags;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.LaunchTaskEvent;
 import com.android.systemui.recents.events.ui.ShowApplicationInfoEvent;
@@ -59,6 +64,8 @@
         implements View.OnClickListener, View.OnLongClickListener {
 
     private static final float HIGHLIGHT_LIGHTNESS_INCREMENT = 0.125f;
+    private static final float OVERLAY_LIGHTNESS_INCREMENT = -0.0625f;
+    private static final int OVERLAY_REVEAL_DURATION = 250;
     private static final long FOCUS_INDICATOR_INTERVAL_MS = 30;
 
     /**
@@ -69,8 +76,6 @@
         private Paint mHighlightPaint = new Paint();
         private Paint mBackgroundPaint = new Paint();
 
-        private float[] mTmpHSL = new float[3];
-
         public HighlightColorDrawable() {
             mBackgroundPaint.setColor(Color.argb(255, 0, 0, 0));
             mBackgroundPaint.setAntiAlias(true);
@@ -122,11 +127,16 @@
     Task mTask;
 
     // Header views
-    ImageView mMoveTaskButton;
-    ImageView mDismissButton;
     ImageView mIconView;
     TextView mTitleView;
-    int mMoveTaskTargetStackId = INVALID_STACK_ID;
+    ImageView mMoveTaskButton;
+    ImageView mDismissButton;
+    ViewStub mAppOverlayViewStub;
+    FrameLayout mAppOverlayView;
+    ImageView mAppIconView;
+    ImageView mAppInfoView;
+    TextView mAppTitleView;
+    ViewStub mFocusTimerIndicatorStub;
     ProgressBar mFocusTimerIndicator;
 
     // Header drawables
@@ -140,21 +150,26 @@
     Drawable mDarkFreeformIcon;
     Drawable mLightFullscreenIcon;
     Drawable mDarkFullscreenIcon;
+    Drawable mLightInfoIcon;
+    Drawable mDarkInfoIcon;
     int mTaskBarViewLightTextColor;
     int mTaskBarViewDarkTextColor;
+    int mMoveTaskTargetStackId = INVALID_STACK_ID;
 
     // Header background
     private HighlightColorDrawable mBackground;
+    private HighlightColorDrawable mOverlayBackground;
+    private float[] mTmpHSL = new float[3];
 
     // Header dim, which is only used when task view hardware layers are not used
     private Paint mDimLayerPaint = new Paint();
 
     Interpolator mFastOutSlowInInterpolator;
     Interpolator mFastOutLinearInInterpolator;
+    Interpolator mLinearOutSlowInInterpolator;
 
-    long mFocusIndicatorProgress;
     private CountDownTimer mFocusTimerCountDown;
-    long mFocusTimerDuration;
+    private long mFocusTimerDuration;
 
     public TaskViewHeader(Context context) {
         this(context, null);
@@ -184,36 +199,45 @@
         mDarkFreeformIcon = context.getDrawable(R.drawable.recents_move_task_freeform_dark);
         mLightFullscreenIcon = context.getDrawable(R.drawable.recents_move_task_fullscreen_light);
         mDarkFullscreenIcon = context.getDrawable(R.drawable.recents_move_task_fullscreen_dark);
+        mLightInfoIcon = context.getDrawable(R.drawable.recents_info_light);
+        mDarkInfoIcon = context.getDrawable(R.drawable.recents_info_dark);
 
         mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
                 com.android.internal.R.interpolator.fast_out_slow_in);
         mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context,
                 com.android.internal.R.interpolator.fast_out_linear_in);
+        mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
+                com.android.internal.R.interpolator.linear_out_slow_in);
 
         // Configure the background and dim
         mBackground = new HighlightColorDrawable();
         mBackground.setColorAndDim(Color.argb(255, 0, 0, 0), 0f);
         setBackground(mBackground);
+        mOverlayBackground = new HighlightColorDrawable();
         mDimLayerPaint.setColor(Color.argb(255, 0, 0, 0));
         mDimLayerPaint.setAntiAlias(true);
         mFocusTimerDuration = res.getInteger(R.integer.recents_auto_advance_duration);
     }
 
+    /**
+     * Resets this header along with the TaskView.
+     */
+    public void reset() {
+        hideAppOverlay(true /* immediate */);
+    }
+
     @Override
     protected void onFinishInflate() {
         // Initialize the icon and description views
         mIconView = (ImageView) findViewById(R.id.icon);
+        mIconView.setClickable(false);
         mIconView.setOnLongClickListener(this);
         mTitleView = (TextView) findViewById(R.id.title);
         mDismissButton = (ImageView) findViewById(R.id.dismiss_task);
         mDismissButton.setOnClickListener(this);
         mMoveTaskButton = (ImageView) findViewById(R.id.move_task);
-        mFocusTimerIndicator = (ProgressBar) findViewById(R.id.focus_timer_indicator);
-
-        // Hide the backgrounds if they are ripple drawables
-        if (mIconView.getBackground() instanceof RippleDrawable) {
-            mIconView.setBackground(null);
-        }
+        mFocusTimerIndicatorStub = (ViewStub) findViewById(R.id.focus_timer_indicator_stub);
+        mAppOverlayViewStub = (ViewStub) findViewById(R.id.app_overlay_stub);
     }
 
     /**
@@ -228,6 +252,7 @@
 
         mTaskViewRect.set(0, 0, width, height);
         boolean updateMoveTaskButton = mMoveTaskButton.getVisibility() != View.GONE;
+        boolean isFreeformTask = (mTask != null) && mTask.isFreeformTask();
         int appIconWidth = mIconView.getMeasuredWidth();
         int activityDescWidth = (mTask != null)
                 ? (int) mTitleView.getPaint().measureText(mTask.title)
@@ -239,19 +264,20 @@
 
         // Priority-wise, we show the activity icon first, the dismiss icon if there is room, the
         // move-task icon if there is room, and then finally, the activity label if there is room
-        if (width < (appIconWidth + dismissIconWidth)) {
+        if (isFreeformTask && width < (appIconWidth + dismissIconWidth)) {
             mTitleView.setVisibility(View.INVISIBLE);
             if (updateMoveTaskButton) {
                 mMoveTaskButton.setVisibility(View.INVISIBLE);
             }
             mDismissButton.setVisibility(View.INVISIBLE);
-        } else if (width < (appIconWidth + dismissIconWidth + moveTaskIconWidth)) {
+        } else if (isFreeformTask && width < (appIconWidth + dismissIconWidth +
+                moveTaskIconWidth)) {
             mTitleView.setVisibility(View.INVISIBLE);
             if (updateMoveTaskButton) {
                 mMoveTaskButton.setVisibility(View.INVISIBLE);
             }
             mDismissButton.setVisibility(View.VISIBLE);
-        } else if (width < (appIconWidth + dismissIconWidth + moveTaskIconWidth +
+        } else if (isFreeformTask && width < (appIconWidth + dismissIconWidth + moveTaskIconWidth +
                 activityDescWidth)) {
             mTitleView.setVisibility(View.INVISIBLE);
             if (updateMoveTaskButton) {
@@ -273,11 +299,6 @@
     }
 
     @Override
-    protected boolean verifyDrawable(Drawable who) {
-        return super.verifyDrawable(who) || (who == mBackground);
-    }
-
-    @Override
     protected void dispatchDraw(Canvas canvas) {
         super.dispatchDraw(canvas);
 
@@ -288,6 +309,10 @@
 
     /** Starts the focus timer. */
     public void startFocusTimerIndicator() {
+        if (mFocusTimerIndicator == null) {
+            return;
+        }
+
         mFocusTimerIndicator.setVisibility(View.VISIBLE);
         mFocusTimerIndicator.setMax((int) mFocusTimerDuration);
         if (mFocusTimerCountDown == null) {
@@ -308,7 +333,11 @@
 
     /** Cancels the focus timer. */
     public void cancelFocusTimerIndicator() {
-        if (mFocusTimerCountDown != null && mFocusTimerIndicator != null) {
+        if (mFocusTimerIndicator == null) {
+            return;
+        }
+
+        if (mFocusTimerCountDown != null) {
             mFocusTimerCountDown.cancel();
             mFocusTimerIndicator.setProgress(0);
             mFocusTimerIndicator.setVisibility(View.INVISIBLE);
@@ -337,6 +366,10 @@
     private void updateBackgroundColor(float dimAlpha) {
         if (mTask != null) {
             mBackground.setColorAndDim(mTask.colorPrimary, dimAlpha);
+            // TODO: Consider using the saturation of the color to adjust the lightness as well
+            ColorUtils.colorToHSL(mTask.colorPrimary, mTmpHSL);
+            mTmpHSL[2] = Math.min(1f, mTmpHSL[2] + OVERLAY_LIGHTNESS_INCREMENT * (1.0f - dimAlpha));
+            mOverlayBackground.setColorAndDim(ColorUtils.HSLToColor(mTmpHSL), dimAlpha);
             mDimLayerPaint.setAlpha((int) (dimAlpha * 255));
         }
     }
@@ -382,10 +415,15 @@
             mMoveTaskButton.setOnClickListener(this);
         }
 
-        mFocusTimerIndicator.getProgressDrawable()
-                .setColorFilter(
-                        getSecondaryColor(t.colorPrimary, t.useLightOnPrimaryColor),
-                        PorterDuff.Mode.SRC_IN);
+        if (Recents.getDebugFlags().isFastToggleIndicatorEnabled()) {
+            if (mFocusTimerIndicator == null) {
+                mFocusTimerIndicator = (ProgressBar) mFocusTimerIndicatorStub.inflate();
+            }
+            mFocusTimerIndicator.getProgressDrawable()
+                    .setColorFilter(
+                            getSecondaryColor(t.colorPrimary, t.useLightOnPrimaryColor),
+                            PorterDuff.Mode.SRC_IN);
+        }
 
         // In accessibility, a single click on the focused app info button will show it
         if (ssp.isTouchExplorationEnabled()) {
@@ -447,8 +485,11 @@
     @Override
     public void onClick(View v) {
         if (v == mIconView) {
-            // In accessibility, a single click on the focused app info button will show it
-            EventBus.getDefault().send(new ShowApplicationInfoEvent(mTask));
+            SystemServicesProxy ssp = Recents.getSystemServices();
+            if (ssp.isTouchExplorationEnabled()) {
+                // In accessibility, a single click on the focused app info button will show it
+                EventBus.getDefault().send(new ShowApplicationInfoEvent(mTask));
+            }
         } else if (v == mDismissButton) {
             TaskView tv = Utilities.findParent(this, TaskView.class);
             tv.dismissTask();
@@ -463,15 +504,92 @@
                     : new Rect();
             EventBus.getDefault().send(new LaunchTaskEvent(tv, mTask, bounds,
                     mMoveTaskTargetStackId, false));
+        } else if (v == mAppInfoView) {
+            EventBus.getDefault().send(new ShowApplicationInfoEvent(mTask));
+        } else if (v == mAppIconView) {
+            hideAppOverlay(false /* immediate */);
         }
     }
 
     @Override
     public boolean onLongClick(View v) {
         if (v == mIconView) {
-            EventBus.getDefault().send(new ShowApplicationInfoEvent(mTask));
+            showAppOverlay();
+            return true;
+        } else if (v == mAppIconView) {
+            hideAppOverlay(false /* immediate */);
             return true;
         }
         return false;
     }
+
+    /**
+     * Shows the application overlay.
+     */
+    private void showAppOverlay() {
+        // Skip early if the task is invalid
+        SystemServicesProxy ssp = Recents.getSystemServices();
+        ComponentName cn = mTask.key.getComponent();
+        int userId = mTask.key.userId;
+        ActivityInfo activityInfo = ssp.getActivityInfo(cn, userId);
+        if (activityInfo == null) {
+            return;
+        }
+
+        // Inflate the overlay if necessary
+        if (mAppOverlayView == null) {
+            mAppOverlayView = (FrameLayout) mAppOverlayViewStub.inflate();
+            mAppOverlayView.setBackground(mOverlayBackground);
+            mAppIconView = (ImageView) mAppOverlayView.findViewById(R.id.app_icon);
+            mAppIconView.setOnClickListener(this);
+            mAppIconView.setOnLongClickListener(this);
+            mAppInfoView = (ImageView) mAppOverlayView.findViewById(R.id.app_info);
+            mAppInfoView.setOnClickListener(this);
+            mAppTitleView = (TextView) mAppOverlayView.findViewById(R.id.app_title);
+        }
+
+        // Update the overlay contents for the current app
+        mAppTitleView.setText(ssp.getBadgedApplicationLabel(activityInfo.applicationInfo, userId));
+        mAppIconView.setImageDrawable(ssp.getBadgedApplicationIcon(activityInfo.applicationInfo, userId));
+        mAppInfoView.setImageDrawable(mTask.useLightOnPrimaryColor
+                ? mLightInfoIcon
+                : mDarkInfoIcon);
+        mAppOverlayView.setVisibility(View.VISIBLE);
+
+        int x = mIconView.getLeft() + mIconView.getWidth() / 2;
+        int y = mIconView.getTop() + mIconView.getHeight() / 2;
+        Animator revealAnim = ViewAnimationUtils.createCircularReveal(mAppOverlayView, x, y, 0,
+                getWidth());
+        revealAnim.setDuration(OVERLAY_REVEAL_DURATION);
+        revealAnim.setInterpolator(mLinearOutSlowInInterpolator);
+        revealAnim.start();
+    }
+
+    /**
+     * Hide the application overlay.
+     */
+    private void hideAppOverlay(boolean immediate) {
+        // Skip if we haven't even loaded the overlay yet
+        if (mAppOverlayView == null) {
+            return;
+        }
+
+        if (immediate) {
+            mAppOverlayView.setVisibility(View.GONE);
+        } else {
+            int x = mIconView.getLeft() + mIconView.getWidth() / 2;
+            int y = mIconView.getTop() + mIconView.getHeight() / 2;
+            Animator revealAnim = ViewAnimationUtils.createCircularReveal(mAppOverlayView, x, y,
+                    getWidth(), 0);
+            revealAnim.setDuration(OVERLAY_REVEAL_DURATION);
+            revealAnim.setInterpolator(mLinearOutSlowInInterpolator);
+            revealAnim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    mAppOverlayView.setVisibility(View.GONE);
+                }
+            });
+            revealAnim.start();
+        }
+    }
 }
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 538c248..85b7c82 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
@@ -88,12 +88,39 @@
     public float alpha = 1f;
 
     public boolean visible = false;
-    float p = 0f;
+
+    // This is the relative task progress of this task, relative to the stack scroll at which this
+    // transform was computed
+    public float p = 0f;
 
     // This is a window-space rect used for positioning the task in the stack and freeform workspace
     public RectF rect = new RectF();
 
     /**
+     * Fills int this transform from the state of the given TaskView.
+     */
+    public void fillIn(TaskView tv) {
+        translationZ = tv.getTranslationZ();
+        scale = tv.getScaleX();
+        alpha = tv.getAlpha();
+        visible = true;
+        p = tv.getTaskProgress();
+        rect.set(tv.getLeft(), tv.getTop(), tv.getRight(), tv.getBottom());
+    }
+
+    /**
+     * Copies the transform state from another {@link TaskViewTransform}.
+     */
+    public void copyFrom(TaskViewTransform other) {
+        translationZ = other.translationZ;
+        scale = other.scale;
+        alpha = other.alpha;
+        visible = other.visible;
+        p = other.p;
+        rect.set(other.rect);
+    }
+
+    /**
      * Resets the current transform.
      */
     public void reset() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index cc30882..68e483c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -351,10 +351,13 @@
 
         for (PhoneState state : mPhoneStates) {
             if (state.mMobile != null) {
+                state.maybeStopAnimatableDrawable(state.mMobile);
                 state.mMobile.setImageDrawable(null);
+                state.mLastMobileStrengthId = -1;
             }
             if (state.mMobileType != null) {
                 state.mMobileType.setImageDrawable(null);
+                state.mLastMobileTypeId = -1;
             }
         }
 
@@ -486,6 +489,8 @@
         private final int mSubId;
         private boolean mMobileVisible = false;
         private int mMobileStrengthId = 0, mMobileTypeId = 0;
+        private int mLastMobileStrengthId = -1;
+        private int mLastMobileTypeId = -1;
         private boolean mIsMobileTypeIconWide;
         private String mMobileDescription, mMobileTypeDescription;
 
@@ -508,25 +513,16 @@
 
         public boolean apply(boolean isSecondaryIcon) {
             if (mMobileVisible && !mIsAirplaneMode) {
-                mMobile.setImageResource(mMobileStrengthId);
-                Drawable mobileDrawable = mMobile.getDrawable();
-                if (mobileDrawable instanceof Animatable) {
-                    Animatable ad = (Animatable) mobileDrawable;
-                    if (!ad.isRunning()) {
-                        ad.start();
-                    }
+                if (mLastMobileStrengthId != mMobileStrengthId) {
+                    updateAnimatableIcon(mMobile, mMobileStrengthId);
+                    updateAnimatableIcon(mMobileDark, mMobileStrengthId);
+                    mLastMobileStrengthId = mMobileStrengthId;
                 }
 
-                mMobileDark.setImageResource(mMobileStrengthId);
-                Drawable mobileDarkDrawable = mMobileDark.getDrawable();
-                if (mobileDarkDrawable instanceof Animatable) {
-                    Animatable ad = (Animatable) mobileDarkDrawable;
-                    if (!ad.isRunning()) {
-                        ad.start();
-                    }
+                if (mLastMobileTypeId != mMobileTypeId) {
+                    mMobileType.setImageResource(mMobileTypeId);
+                    mLastMobileTypeId = mMobileTypeId;
                 }
-
-                mMobileType.setImageResource(mMobileTypeId);
                 mMobileGroup.setContentDescription(mMobileTypeDescription
                         + " " + mMobileDescription);
                 mMobileGroup.setVisibility(View.VISIBLE);
@@ -550,6 +546,32 @@
             return mMobileVisible;
         }
 
+        private void updateAnimatableIcon(ImageView view, int resId) {
+            maybeStopAnimatableDrawable(view);
+            view.setImageResource(resId);
+            maybeStartAnimatableDrawable(view);
+        }
+
+        private void maybeStopAnimatableDrawable(ImageView view) {
+            Drawable drawable = view.getDrawable();
+            if (drawable instanceof Animatable) {
+                Animatable ad = (Animatable) drawable;
+                if (ad.isRunning()) {
+                    ad.stop();
+                }
+            }
+        }
+
+        private void maybeStartAnimatableDrawable(ImageView view) {
+            Drawable drawable = view.getDrawable();
+            if (drawable instanceof Animatable) {
+                Animatable ad = (Animatable) drawable;
+                if (!ad.isRunning()) {
+                    ad.start();
+                }
+            }
+        }
+
         public void populateAccessibilityEvent(AccessibilityEvent event) {
             if (mMobileVisible && mMobileGroup != null
                     && mMobileGroup.getContentDescription() != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/UserGridView.java b/packages/SystemUI/src/com/android/systemui/statusbar/UserGridView.java
index 32caf9f..2f8bc2d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/UserGridView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/UserGridView.java
@@ -137,7 +137,7 @@
             if (convertView == null) {
                 LayoutInflater inflater = (LayoutInflater)getContext().getSystemService
                         (Context.LAYOUT_INFLATER_SERVICE);
-                convertView = inflater.inflate(R.layout.fullscreen_user_pod, null);
+                convertView = inflater.inflate(R.layout.car_fullscreen_user_pod, null);
             }
             UserSwitcherController.UserRecord record = getItem(position);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
index 4f57906..a444934 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
@@ -83,7 +83,7 @@
             if (location != null) {
                 int iconId = location.equals("show") ? LocationControllerImpl.LOCATION_STATUS_ICON_ID
                         : 0;
-                updateSlot(LocationControllerImpl.LOCATION_STATUS_ICON_PLACEHOLDER, null, iconId);
+                updateSlot("location", null, iconId);
             }
             String alarm = args.getString("alarm");
             if (alarm != null) {
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 2db0804..8bf4572 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
@@ -162,11 +162,16 @@
         mDockWindowTouchSlopExceeded = false;
         mTouchDownX = (int) event.getX();
         mTouchDownY = (int) event.getY();
-        View recentsButton = mNavigationBarView.getRecentsButton();
-        mDownOnRecents = mTouchDownX >= recentsButton.getLeft()
-                && mTouchDownX <= recentsButton.getRight()
-                && mTouchDownY >= recentsButton.getTop()
-                && mTouchDownY <= recentsButton.getBottom();
+
+        if (mNavigationBarView != null) {
+            View recentsButton = mNavigationBarView.getRecentsButton();
+            if (recentsButton != null) {
+                mDownOnRecents = mTouchDownX >= recentsButton.getLeft()
+                        && mTouchDownX <= recentsButton.getRight()
+                        && mTouchDownY >= recentsButton.getTop()
+                        && mTouchDownY <= recentsButton.getBottom();
+            }
+        }
     }
 
     private boolean handleDragActionMoveEvent(MotionEvent event) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index efa8f5b..5309903 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -21,6 +21,7 @@
 import android.animation.ObjectAnimator;
 import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
+import android.annotation.Nullable;
 import android.app.ActivityManagerNative;
 import android.app.StatusBarManager;
 import android.content.Context;
@@ -131,12 +132,15 @@
         }
 
         public void onBackAltCleared() {
+            View backButton = getBackButton();
+            View homeButton = getHomeButton();
+
             // When dismissing ime during unlock, force the back button to run the same appearance
             // animation as home (if we catch this condition early enough).
-            if (!mBackTransitioning && getBackButton().getVisibility() == VISIBLE
-                    && mHomeAppearing && getHomeButton().getAlpha() == 0) {
+            if (backButton != null && !mBackTransitioning && backButton.getVisibility() == VISIBLE
+                    && mHomeAppearing && homeButton != null && getHomeButton().getAlpha() == 0) {
                 getBackButton().setAlpha(0);
-                ValueAnimator a = ObjectAnimator.ofFloat(getBackButton(), "alpha", 0, 1);
+                ValueAnimator a = ObjectAnimator.ofFloat(backButton, "alpha", 0, 1);
                 a.setStartDelay(mStartDelay);
                 a.setDuration(mDuration);
                 a.setInterpolator(mInterpolator);
@@ -222,7 +226,10 @@
     }
 
     public void abortCurrentGesture() {
-        getHomeButton().abortCurrentGesture();
+        View homeButton = getHomeButton();
+        if (homeButton != null) {
+            getHomeButton().abortCurrentGesture();
+        }
     }
 
     private H mHandler = new H();
@@ -235,26 +242,34 @@
         return mRotatedViews;
     }
 
+    // The following Buttons can possibly return null if NavigationBarView is extended to provide
+    // a different layout and the buttons do not exist in that new layout.
+    @Nullable
     public KeyButtonView getRecentsButton() {
         return (KeyButtonView) getCurrentView().findViewById(R.id.recent_apps);
     }
 
+    @Nullable
     public View getMenuButton() {
         return getCurrentView().findViewById(R.id.menu);
     }
 
+    @Nullable
     public View getBackButton() {
         return getCurrentView().findViewById(R.id.back);
     }
 
+    @Nullable
     public KeyButtonView getHomeButton() {
         return (KeyButtonView) getCurrentView().findViewById(R.id.home);
     }
 
+    @Nullable
     public View getImeSwitchButton() {
         return getCurrentView().findViewById(R.id.ime_switcher);
     }
 
+    @Nullable
     public View getAppShelf() {
         return getCurrentView().findViewById(R.id.app_shelf);
     }
@@ -329,19 +344,27 @@
                 ? getBackIconWithAlt(mCarMode, mVertical)
                 : getBackIcon(mCarMode, mVertical);
 
-        ((ImageView) getBackButton()).setImageDrawable(backIcon);
+        View backButton = getBackButton();
+        if (backButton != null && backButton instanceof ImageView) {
+            ((ImageView) backButton).setImageDrawable(backIcon);
+        }
 
-        ((ImageView) getRecentsButton()).setImageDrawable(
-                mVertical ? mRecentLandIcon : mRecentIcon);
+        ImageView recentsButton = getRecentsButton();
+        if (recentsButton != null) {
+            recentsButton.setImageDrawable(mVertical ? mRecentLandIcon : mRecentIcon);
+        }
 
-        if (mCarMode) {
-            ((ImageView) getHomeButton()).setImageDrawable(mHomeCarModeIcon);
-        } else {
-            ((ImageView) getHomeButton()).setImageDrawable(mHomeDefaultIcon);
+        ImageView homeButton = getHomeButton();
+        if (homeButton != null) {
+            homeButton.setImageDrawable(mCarMode ? mHomeCarModeIcon : mHomeDefaultIcon);
         }
 
         final boolean showImeButton = ((hints & StatusBarManager.NAVIGATION_HINT_IME_SHOWN) != 0);
-        getImeSwitchButton().setVisibility(showImeButton ? View.VISIBLE : View.INVISIBLE);
+        View imeSwitchButton = getImeSwitchButton();
+        if (imeSwitchButton != null) {
+            imeSwitchButton.setVisibility(showImeButton ? View.VISIBLE : View.INVISIBLE);
+        }
+
         // Update menu button in case the IME state has changed.
         setMenuVisibility(mShowMenu, true);
 
@@ -382,9 +405,20 @@
             disableRecent = false;
         }
 
-        getBackButton()   .setVisibility(disableBack       ? View.INVISIBLE : View.VISIBLE);
-        getHomeButton()   .setVisibility(disableHome       ? View.INVISIBLE : View.VISIBLE);
-        getRecentsButton().setVisibility(disableRecent     ? View.INVISIBLE : View.VISIBLE);
+        View backButton = getBackButton();
+        if (backButton != null) {
+            backButton.setVisibility(disableBack ? View.INVISIBLE : View.VISIBLE);
+        }
+
+        View homeButton = getHomeButton();
+        if (homeButton != null) {
+            homeButton.setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE);
+        }
+
+        View recentsButton = getRecentsButton();
+        if (recentsButton != null) {
+            recentsButton.setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
+        }
 
         // The app shelf, if it exists, follows the visibility of the home button.
         View appShelf = getAppShelf();
@@ -475,7 +509,11 @@
         // Only show Menu if IME switcher not shown.
         final boolean shouldShow = mShowMenu &&
                 ((mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_IME_SHOWN) == 0);
-        getMenuButton().setVisibility(shouldShow ? View.VISIBLE : View.INVISIBLE);
+
+        View menuButton = getMenuButton();
+        if (menuButton != null) {
+            menuButton.setVisibility(shouldShow ? View.VISIBLE : View.INVISIBLE);
+        }
     }
 
     @Override
@@ -489,7 +527,10 @@
 
         mCurrentView = mRotatedViews[Surface.ROTATION_0];
 
-        getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
+        View imeSwitchButton = getImeSwitchButton();
+        if (imeSwitchButton != null) {
+            imeSwitchButton.setOnClickListener(mImeSwitcherClickListener);
+        }
 
         updateRTLOrder();
 
@@ -515,9 +556,13 @@
     }
 
     private void updateRecentsIcon(boolean dockedStackExists) {
-        getRecentsButton().setImageResource(dockedStackExists
-                ? R.drawable.ic_sysbar_docked
-                : R.drawable.ic_sysbar_recent);
+        ImageView recentsButton = getRecentsButton();
+
+        if (recentsButton != null) {
+            recentsButton.setImageResource(dockedStackExists
+                    ? R.drawable.ic_sysbar_docked
+                    : R.drawable.ic_sysbar_recent);
+        }
     }
 
     public boolean isVertical() {
@@ -533,7 +578,10 @@
         mCurrentView.setVisibility(View.VISIBLE);
         updateLayoutTransitionsEnabled();
 
-        getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
+        View imeSwitchButton = getImeSwitchButton();
+        if (imeSwitchButton != null) {
+            imeSwitchButton.setOnClickListener(mImeSwitcherClickListener);
+        }
 
         mDeadZone = (DeadZone) mCurrentView.findViewById(R.id.deadzone);
 
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 c853fb4..7a4adbc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -269,7 +269,7 @@
     // These are no longer handled by the policy, because we need custom strategies for them
     BluetoothControllerImpl mBluetoothController;
     SecurityControllerImpl mSecurityController;
-    BatteryController mBatteryController;
+    protected BatteryController mBatteryController;
     LocationControllerImpl mLocationController;
     NetworkControllerImpl mNetworkController;
     HotspotControllerImpl mHotspotController;
@@ -633,7 +633,8 @@
 
         // Lastly, call to the icon policy to install/update all the icons.
         mIconPolicy = new PhoneStatusBarPolicy(mContext, mIconController, mCastController,
-                mHotspotController, mUserInfoController, mBluetoothController);
+                mHotspotController, mUserInfoController, mBluetoothController,
+                mRotationLockController);
         mIconPolicy.setCurrentUserSetup(mUserSetup);
         mSettingsObserver.onChange(false); // set up
 
@@ -934,14 +935,7 @@
     }
 
     protected void createNavigationBarView(Context context) {
-    // Optionally show app shortcuts in the nav bar "shelf" area.
-        if (shouldShowAppShelf()) {
-            mNavigationBarView = (NavigationBarView) View.inflate(
-                    context, R.layout.navigation_bar_with_apps, null);
-        } else {
-            mNavigationBarView = (NavigationBarView) View.inflate(
-                    context, R.layout.navigation_bar, null);
-        }
+        inflateNavigationBarView(context);
         mNavigationBarView.setDisabledFlags(mDisabled1);
         mNavigationBarView.setComponents(mRecents, getComponent(Divider.class));
         mNavigationBarView.setOnVerticalChangedListener(
@@ -962,7 +956,18 @@
             }});
     }
 
-    private void initSignalCluster(View containerView) {
+    protected void inflateNavigationBarView(Context context) {
+        // Optionally show app shortcuts in the nav bar "shelf" area.
+        if (shouldShowAppShelf()) {
+            mNavigationBarView = (NavigationBarView) View.inflate(
+                    context, R.layout.navigation_bar_with_apps, null);
+        } else {
+            mNavigationBarView = (NavigationBarView) View.inflate(
+                    context, R.layout.navigation_bar, null);
+        }
+    }
+
+    protected void initSignalCluster(View containerView) {
         SignalClusterView signalCluster =
                 (SignalClusterView) containerView.findViewById(R.id.signal_cluster);
         if (signalCluster != null) {
@@ -1179,14 +1184,26 @@
     private void prepareNavigationBarView() {
         mNavigationBarView.reorient();
 
-        mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
-        mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener);
-        mNavigationBarView.getRecentsButton().setLongClickable(true);
-        mNavigationBarView.getRecentsButton().setOnLongClickListener(mRecentsLongClickListener);
-        mNavigationBarView.getBackButton().setLongClickable(true);
-        mNavigationBarView.getBackButton().setOnLongClickListener(mLongPressBackListener);
-        mNavigationBarView.getHomeButton().setOnTouchListener(mHomeActionListener);
-        mNavigationBarView.getHomeButton().setOnLongClickListener(mLongPressHomeListener);
+        View recentsButton = mNavigationBarView.getRecentsButton();
+        if (recentsButton != null) {
+            recentsButton.setOnClickListener(mRecentsClickListener);
+            recentsButton.setOnTouchListener(mRecentsPreloadOnTouchListener);
+            recentsButton.setLongClickable(true);
+            recentsButton.setOnLongClickListener(mRecentsLongClickListener);
+        }
+
+        View backButton = mNavigationBarView.getBackButton();
+        if (backButton != null) {
+            backButton.setLongClickable(true);
+            backButton.setOnLongClickListener(mLongPressBackListener);
+        }
+
+        View homeButton = mNavigationBarView.getHomeButton();
+        if (homeButton != null) {
+            homeButton.setOnTouchListener(mHomeActionListener);
+            homeButton.setOnLongClickListener(mLongPressHomeListener);
+        }
+
         mAssistManager.onConfigurationChanged();
     }
 
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 59d831c..37d61b9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -38,11 +38,13 @@
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.systemui.R;
 import com.android.systemui.qs.tiles.DndTile;
+import com.android.systemui.qs.tiles.RotationLockTile;
 import com.android.systemui.statusbar.policy.BluetoothController;
 import com.android.systemui.statusbar.policy.BluetoothController.Callback;
 import com.android.systemui.statusbar.policy.CastController;
 import com.android.systemui.statusbar.policy.CastController.CastDevice;
 import com.android.systemui.statusbar.policy.HotspotController;
+import com.android.systemui.statusbar.policy.RotationLockController;
 import com.android.systemui.statusbar.policy.UserInfoController;
 
 /**
@@ -50,18 +52,20 @@
  * bar at boot time.  It goes through the normal API for icons, even though it probably
  * strictly doesn't need to.
  */
-public class PhoneStatusBarPolicy implements Callback {
+public class PhoneStatusBarPolicy implements Callback, RotationLockController.RotationLockControllerCallback {
     private static final String TAG = "PhoneStatusBarPolicy";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
-    private static final String SLOT_CAST = "cast";
-    private static final String SLOT_HOTSPOT = "hotspot";
-    private static final String SLOT_BLUETOOTH = "bluetooth";
-    private static final String SLOT_TTY = "tty";
-    private static final String SLOT_ZEN = "zen";
-    private static final String SLOT_VOLUME = "volume";
-    private static final String SLOT_ALARM_CLOCK = "alarm_clock";
-    private static final String SLOT_MANAGED_PROFILE = "managed_profile";
+    private final String mSlotCast;
+    private final String mSlotHotspot;
+    private final String mSlotBluetooth;
+    private final String mSlotTty;
+    private final String mSlotZen;
+    private final String mSlotVolume;
+    private final String mSlotAlarmClock;
+    private final String mSlotManagedProfile;
+    private final String mSlotRotate;
+    private final String mSlotHeadset;
 
     private final Context mContext;
     private final Handler mHandler = new Handler();
@@ -71,6 +75,7 @@
     private final UserInfoController mUserInfoController;
     private final UserManager mUserManager;
     private final StatusBarIconController mIconController;
+    private final RotationLockController mRotationLockController;
 
     // Assume it's all good unless we hear otherwise.  We don't always seem
     // to get broadcasts that it *is* there.
@@ -89,37 +94,9 @@
     private boolean mKeyguardVisible = true;
     private BluetoothController mBluetooth;
 
-    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (action.equals(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED)) {
-                updateAlarm();
-            } else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION) ||
-                    action.equals(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION)) {
-                updateVolumeZen();
-            } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
-                updateSimState(intent);
-            } else if (action.equals(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED)) {
-                updateTTY(intent);
-            } else if (action.equals(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED)) {
-                updateQuietState();
-                updateManagedProfile();
-            }
-        }
-    };
-
-    private Runnable mRemoveCastIconRunnable = new Runnable() {
-        @Override
-        public void run() {
-            if (DEBUG) Log.v(TAG, "updateCast: hiding icon NOW");
-            mIconController.setIconVisibility(SLOT_CAST, false);
-        }
-    };
-
     public PhoneStatusBarPolicy(Context context, StatusBarIconController iconController,
             CastController cast, HotspotController hotspot, UserInfoController userInfoController,
-            BluetoothController bluetooth) {
+            BluetoothController bluetooth, RotationLockController rotationLockController) {
         mContext = context;
         mIconController = iconController;
         mCast = cast;
@@ -129,12 +106,28 @@
         mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
         mUserInfoController = userInfoController;
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        mRotationLockController = rotationLockController;
+
+        mSlotCast = context.getString(com.android.internal.R.string.status_bar_cast);
+        mSlotHotspot = context.getString(com.android.internal.R.string.status_bar_hotspot);
+        mSlotBluetooth = context.getString(com.android.internal.R.string.status_bar_bluetooth);
+        mSlotTty = context.getString(com.android.internal.R.string.status_bar_tty);
+        mSlotZen = context.getString(com.android.internal.R.string.status_bar_zen);
+        mSlotVolume = context.getString(com.android.internal.R.string.status_bar_volume);
+        mSlotAlarmClock = context.getString(com.android.internal.R.string.status_bar_alarm_clock);
+        mSlotManagedProfile = context.getString(
+                com.android.internal.R.string.status_bar_managed_profile);
+        mSlotRotate = context.getString(com.android.internal.R.string.status_bar_rotate);
+        mSlotHeadset = context.getString(com.android.internal.R.string.status_bar_headset);
+
+        mRotationLockController.addRotationLockControllerCallback(this);
 
         // listen for broadcasts
         IntentFilter filter = new IntentFilter();
         filter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
         filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
         filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
+        filter.addAction(AudioManager.ACTION_HEADSET_PLUG);
         filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
         filter.addAction(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED);
         filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED);
@@ -148,40 +141,40 @@
         }
 
         // TTY status
-        mIconController.setIcon(SLOT_TTY,  R.drawable.stat_sys_tty_mode, null);
-        mIconController.setIconVisibility(SLOT_TTY, false);
+        mIconController.setIcon(mSlotTty,  R.drawable.stat_sys_tty_mode, null);
+        mIconController.setIconVisibility(mSlotTty, false);
 
         // bluetooth status
         updateBluetooth();
 
         // Alarm clock
-        mIconController.setIcon(SLOT_ALARM_CLOCK, R.drawable.stat_sys_alarm, null);
-        mIconController.setIconVisibility(SLOT_ALARM_CLOCK, false);
+        mIconController.setIcon(mSlotAlarmClock, R.drawable.stat_sys_alarm, null);
+        mIconController.setIconVisibility(mSlotAlarmClock, false);
 
         // zen
-        mIconController.setIcon(SLOT_ZEN, R.drawable.stat_sys_zen_important, null);
-        mIconController.setIconVisibility(SLOT_ZEN, false);
+        mIconController.setIcon(mSlotZen, R.drawable.stat_sys_zen_important, null);
+        mIconController.setIconVisibility(mSlotZen, false);
 
         // volume
-        mIconController.setIcon(SLOT_VOLUME, R.drawable.stat_sys_ringer_vibrate, null);
-        mIconController.setIconVisibility(SLOT_VOLUME, false);
+        mIconController.setIcon(mSlotVolume, R.drawable.stat_sys_ringer_vibrate, null);
+        mIconController.setIconVisibility(mSlotVolume, false);
         updateVolumeZen();
 
         // cast
-        mIconController.setIcon(SLOT_CAST, R.drawable.stat_sys_cast, null);
-        mIconController.setIconVisibility(SLOT_CAST, false);
+        mIconController.setIcon(mSlotCast, R.drawable.stat_sys_cast, null);
+        mIconController.setIconVisibility(mSlotCast, false);
         mCast.addCallback(mCastCallback);
 
         // hotspot
-        mIconController.setIcon(SLOT_HOTSPOT, R.drawable.stat_sys_hotspot,
+        mIconController.setIcon(mSlotHotspot, R.drawable.stat_sys_hotspot,
                 mContext.getString(R.string.accessibility_status_bar_hotspot));
-        mIconController.setIconVisibility(SLOT_HOTSPOT, mHotspot.isHotspotEnabled());
+        mIconController.setIconVisibility(mSlotHotspot, mHotspot.isHotspotEnabled());
         mHotspot.addCallback(mHotspotCallback);
 
         // managed profile
-        mIconController.setIcon(SLOT_MANAGED_PROFILE, R.drawable.stat_sys_managed_profile_status,
+        mIconController.setIcon(mSlotManagedProfile, R.drawable.stat_sys_managed_profile_status,
                 mContext.getString(R.string.accessibility_managed_profile));
-        mIconController.setIconVisibility(SLOT_MANAGED_PROFILE, mManagedProfileIconVisible);
+        mIconController.setIconVisibility(mSlotManagedProfile, mManagedProfileIconVisible);
     }
 
     public void setZenMode(int zen) {
@@ -193,9 +186,9 @@
         final AlarmClockInfo alarm = mAlarmManager.getNextAlarmClock(UserHandle.USER_CURRENT);
         final boolean hasAlarm = alarm != null && alarm.getTriggerTime() > 0;
         final boolean zenNone = mZen == Global.ZEN_MODE_NO_INTERRUPTIONS;
-        mIconController.setIcon(SLOT_ALARM_CLOCK, zenNone ? R.drawable.stat_sys_alarm_dim
+        mIconController.setIcon(mSlotAlarmClock, zenNone ? R.drawable.stat_sys_alarm_dim
                 : R.drawable.stat_sys_alarm, null);
-        mIconController.setIconVisibility(SLOT_ALARM_CLOCK, mCurrentUserSetup && hasAlarm);
+        mIconController.setIconVisibility(mSlotAlarmClock, mCurrentUserSetup && hasAlarm);
     }
 
     private final void updateSimState(Intent intent) {
@@ -260,18 +253,18 @@
         }
 
         if (zenVisible) {
-            mIconController.setIcon(SLOT_ZEN, zenIconId, zenDescription);
+            mIconController.setIcon(mSlotZen, zenIconId, zenDescription);
         }
         if (zenVisible != mZenVisible) {
-            mIconController.setIconVisibility(SLOT_ZEN, zenVisible);
+            mIconController.setIconVisibility(mSlotZen, zenVisible);
             mZenVisible = zenVisible;
         }
 
         if (volumeVisible) {
-            mIconController.setIcon(SLOT_VOLUME, volumeIconId, volumeDescription);
+            mIconController.setIcon(mSlotVolume, volumeIconId, volumeDescription);
         }
         if (volumeVisible != mVolumeVisible) {
-            mIconController.setIconVisibility(SLOT_VOLUME, volumeVisible);
+            mIconController.setIconVisibility(mSlotVolume, volumeVisible);
             mVolumeVisible = volumeVisible;
         }
         updateAlarm();
@@ -300,8 +293,8 @@
             }
         }
 
-        mIconController.setIcon(SLOT_BLUETOOTH, iconId, contentDescription);
-        mIconController.setIconVisibility(SLOT_BLUETOOTH, bluetoothEnabled);
+        mIconController.setIcon(mSlotBluetooth, iconId, contentDescription);
+        mIconController.setIconVisibility(mSlotBluetooth, bluetoothEnabled);
     }
 
     private final void updateTTY(Intent intent) {
@@ -314,13 +307,13 @@
         if (enabled) {
             // TTY is on
             if (DEBUG) Log.v(TAG, "updateTTY: set TTY on");
-            mIconController.setIcon(SLOT_TTY, R.drawable.stat_sys_tty_mode,
+            mIconController.setIcon(mSlotTty, R.drawable.stat_sys_tty_mode,
                     mContext.getString(R.string.accessibility_tty_enabled));
-            mIconController.setIconVisibility(SLOT_TTY, true);
+            mIconController.setIconVisibility(mSlotTty, true);
         } else {
             // TTY is off
             if (DEBUG) Log.v(TAG, "updateTTY: set TTY off");
-            mIconController.setIconVisibility(SLOT_TTY, false);
+            mIconController.setIconVisibility(mSlotTty, false);
         }
     }
 
@@ -336,9 +329,9 @@
         if (DEBUG) Log.v(TAG, "updateCast: isCasting: " + isCasting);
         mHandler.removeCallbacks(mRemoveCastIconRunnable);
         if (isCasting) {
-            mIconController.setIcon(SLOT_CAST, R.drawable.stat_sys_cast,
+            mIconController.setIcon(mSlotCast, R.drawable.stat_sys_cast,
                     mContext.getString(R.string.accessibility_casting));
-            mIconController.setIconVisibility(SLOT_CAST, true);
+            mIconController.setIconVisibility(mSlotCast, true);
         } else {
             // don't turn off the screen-record icon for a few seconds, just to make sure the user
             // has seen it
@@ -382,19 +375,19 @@
         final boolean showIcon;
         if (mManagedProfileFocused && !mKeyguardVisible) {
             showIcon = true;
-            mIconController.setIcon(SLOT_MANAGED_PROFILE,
+            mIconController.setIcon(mSlotManagedProfile,
                     R.drawable.stat_sys_managed_profile_status,
                     mContext.getString(R.string.accessibility_managed_profile));
         } else if (mManagedProfileInQuietMode) {
             showIcon = true;
-            mIconController.setIcon(SLOT_MANAGED_PROFILE,
+            mIconController.setIcon(mSlotManagedProfile,
                     R.drawable.stat_sys_managed_profile_status_off,
                     mContext.getString(R.string.accessibility_managed_profile));
         } else {
             showIcon = false;
         }
         if (mManagedProfileIconVisible != showIcon) {
-            mIconController.setIconVisibility(SLOT_MANAGED_PROFILE, showIcon);
+            mIconController.setIconVisibility(mSlotManagedProfile, showIcon);
             mManagedProfileIconVisible = showIcon;
         }
     }
@@ -423,7 +416,7 @@
     private final HotspotController.Callback mHotspotCallback = new HotspotController.Callback() {
         @Override
         public void onHotspotChanged(boolean enabled) {
-            mIconController.setIconVisibility(SLOT_HOTSPOT, enabled);
+            mIconController.setIconVisibility(mSlotHotspot, enabled);
         }
     };
 
@@ -449,4 +442,69 @@
         updateAlarm();
         updateQuietState();
     }
+
+    @Override
+    public void onRotationLockStateChanged(boolean rotationLocked, boolean affordanceVisible) {
+        boolean portrait = RotationLockTile.isCurrentOrientationLockPortrait(
+                mRotationLockController, mContext);
+        if (rotationLocked) {
+            if (portrait) {
+                mIconController.setIcon(mSlotRotate, R.drawable.stat_sys_rotate_portrait,
+                        mContext.getString(R.string.accessibility_rotation_lock_on_portrait));
+            } else {
+                mIconController.setIcon(mSlotRotate, R.drawable.stat_sys_rotate_landscape,
+                        mContext.getString(R.string.accessibility_rotation_lock_on_landscape));
+            }
+        } else {
+            mIconController.setIcon(mSlotRotate, portrait
+                    ? R.drawable.stat_sys_auto_rotate_portrait
+                    : R.drawable.stat_sys_auto_rotate_landscape,
+                    mContext.getString(R.string.accessibility_rotation_lock_off));
+        }
+    }
+
+    private void updateHeadsetPlug(Intent intent) {
+        boolean connected = intent.getIntExtra("state", 0) != 0;
+        boolean hasMic = intent.getIntExtra("microphone", 0) != 0;
+        if (connected) {
+            String contentDescription = mContext.getString(hasMic
+                    ? R.string.accessibility_status_bar_headset
+                    : R.string.accessibility_status_bar_headphones);
+            mIconController.setIcon(mSlotHeadset, hasMic ? R.drawable.ic_headset_mic
+                    : R.drawable.ic_headset, contentDescription);
+            mIconController.setIconVisibility(mSlotHeadset, true);
+        } else {
+            mIconController.setIconVisibility(mSlotHeadset, false);
+        }
+    }
+
+    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED)) {
+                updateAlarm();
+            } else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION) ||
+                    action.equals(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION)) {
+                updateVolumeZen();
+            } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
+                updateSimState(intent);
+            } else if (action.equals(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED)) {
+                updateTTY(intent);
+            } else if (action.equals(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED)) {
+                updateQuietState();
+                updateManagedProfile();
+            } else if (action.equals(AudioManager.ACTION_HEADSET_PLUG)) {
+                updateHeadsetPlug(intent);
+            }
+        }
+    };
+
+    private Runnable mRemoveCastIconRunnable = new Runnable() {
+        @Override
+        public void run() {
+            if (DEBUG) Log.v(TAG, "updateCast: hiding icon NOW");
+            mIconController.setIconVisibility(mSlotCast, false);
+        }
+    };
 }
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 29ad5d1c..7e27856 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -295,6 +295,7 @@
             if (mTiles.containsKey(tileSpec)) {
                 QSTile<?> tile = mTiles.get(tileSpec);
                 if (DEBUG) Log.d(TAG, "Adding " + tile);
+                tile.removeCallbacks();
                 newTiles.put(tileSpec, tile);
             } else {
                 if (DEBUG) Log.d(TAG, "Creating tile: " + tileSpec);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index 0eb0bf89..b16c98e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -450,12 +450,13 @@
 
     public static ArraySet<String> getIconBlacklist(String blackListStr) {
         ArraySet<String> ret = new ArraySet<String>();
-        if (blackListStr != null) {
-            String[] blacklist = blackListStr.split(",");
-            for (String slot : blacklist) {
-                if (!TextUtils.isEmpty(slot)) {
-                    ret.add(slot);
-                }
+        if (blackListStr == null) {
+            blackListStr = "rotate,headset";
+        }
+        String[] blacklist = blackListStr.split(",");
+        for (String slot : blacklist) {
+            if (!TextUtils.isEmpty(slot)) {
+                ret.add(slot);
             }
         }
         return ret;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 896bd62..7054bb8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -31,15 +31,16 @@
 import android.text.format.DateFormat;
 import android.text.style.CharacterStyle;
 import android.text.style.RelativeSizeSpan;
+import android.util.ArraySet;
 import android.util.AttributeSet;
 import android.view.Display;
+import android.view.View;
 import android.widget.TextView;
-
 import com.android.systemui.DemoMode;
 import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerService.Tunable;
-
 import libcore.icu.LocaleData;
 
 import java.text.SimpleDateFormat;
@@ -87,7 +88,6 @@
         } finally {
             a.recycle();
         }
-        TunerService.get(context).addTunable(this, CLOCK_SECONDS);
     }
 
     @Override
@@ -106,6 +106,8 @@
 
             getContext().registerReceiverAsUser(mIntentReceiver, UserHandle.ALL, filter,
                     null, getHandler());
+            TunerService.get(getContext()).addTunable(this, CLOCK_SECONDS,
+                    StatusBarIconController.ICON_BLACKLIST);
         }
 
         // NOTE: It's safe to do these after registering the receiver since the receiver always runs
@@ -125,6 +127,7 @@
         if (mAttached) {
             getContext().unregisterReceiver(mIntentReceiver);
             mAttached = false;
+            TunerService.get(getContext()).removeTunable(this);
         }
     }
 
@@ -157,8 +160,13 @@
 
     @Override
     public void onTuningChanged(String key, String newValue) {
-        mShowSeconds = newValue != null && Integer.parseInt(newValue) != 0;
-        updateShowSeconds();
+        if (CLOCK_SECONDS.equals(key)) {
+            mShowSeconds = newValue != null && Integer.parseInt(newValue) != 0;
+            updateShowSeconds();
+        } else if (StatusBarIconController.ICON_BLACKLIST.equals(key)) {
+            ArraySet<String> list = StatusBarIconController.getIconBlacklist(newValue);
+            setVisibility(list.contains("clock") ? View.GONE : View.VISIBLE);
+        }
     }
 
     private void updateShowSeconds() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
index 0917528..7517f97 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
@@ -43,7 +43,6 @@
 public class LocationControllerImpl extends BroadcastReceiver implements LocationController {
     // The name of the placeholder corresponding to the location request status icon.
     // This string corresponds to config_statusBarIcons in core/res/res/values/config.xml.
-    public static final String LOCATION_STATUS_ICON_PLACEHOLDER = "location";
     public static final int LOCATION_STATUS_ICON_ID = R.drawable.stat_sys_location;
 
     private static final int[] mHighPowerRequestAppOpArray
@@ -59,9 +58,11 @@
     private ArrayList<LocationSettingsChangeCallback> mSettingsChangeCallbacks =
             new ArrayList<LocationSettingsChangeCallback>();
     private final H mHandler = new H();
+    public final String mSlotLocation;
 
     public LocationControllerImpl(Context context, Looper bgLooper) {
         mContext = context;
+        mSlotLocation = mContext.getString(com.android.internal.R.string.status_bar_location);
 
         // Register to listen for changes in location settings.
         IntentFilter filter = new IntentFilter();
@@ -173,10 +174,10 @@
     // Updates the status view based on the current state of location requests.
     private void refreshViews() {
         if (mAreActiveLocationRequests) {
-            mStatusBarManager.setIcon(LOCATION_STATUS_ICON_PLACEHOLDER, LOCATION_STATUS_ICON_ID,
+            mStatusBarManager.setIcon(mSlotLocation, LOCATION_STATUS_ICON_ID,
                     0, mContext.getString(R.string.accessibility_location_active));
         } else {
-            mStatusBarManager.removeIcon(LOCATION_STATUS_ICON_PLACEHOLDER);
+            mStatusBarManager.removeIcon(mSlotLocation);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/QSPagingSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/QSPagingSwitch.java
deleted file mode 100644
index d19a825..0000000
--- a/packages/SystemUI/src/com/android/systemui/tuner/QSPagingSwitch.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.android.systemui.tuner;
-
-import android.content.Context;
-import android.provider.Settings;
-import android.util.AttributeSet;
-
-import com.android.systemui.statusbar.phone.QSTileHost;
-
-public class QSPagingSwitch extends TunerSwitch {
-
-    public static final String QS_PAGE_TILES =
-            "dnd,cell,battery,user,rotation,flashlight,location,"
-             + "hotspot,inversion,cast";
-
-    public QSPagingSwitch(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    protected boolean persistBoolean(boolean value) {
-        Settings.Secure.putString(getContext().getContentResolver(), QSTileHost.TILES_SETTING,
-                value ? QS_PAGE_TILES : "default");
-        return super.persistBoolean(value);
-    }
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
index 2aac69a..3d91d62 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
@@ -29,6 +29,7 @@
 import android.graphics.Rect;
 import android.os.Handler;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -37,6 +38,9 @@
 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 
+import android.app.ActivityManager;
+import android.app.ActivityManager.RunningTaskInfo;
+
 /**
  * Manages the picture-in-picture (PIP) UI and states.
  */
@@ -46,10 +50,15 @@
 
     private static PipManager sPipManager;
 
+    private static final int MAX_RUNNING_TASKS_COUNT = 10;
+
     private static final int STATE_NO_PIP = 0;
     private static final int STATE_PIP_OVERLAY = 1;
     private static final int STATE_PIP_MENU = 2;
 
+    private static final int TASK_ID_NO_PIP = -1;
+    private static final int INVALID_RESOURCE_TYPE = -1;
+
     private Context mContext;
     private IActivityManager mActivityManager;
     private int mState = STATE_NO_PIP;
@@ -58,6 +67,8 @@
     private Rect mPipBound;
     private Rect mMenuModePipBound;
     private boolean mInitialized;
+    private int mPipTaskId = TASK_ID_NO_PIP;
+
     private final Runnable mOnActivityPinnedRunnable = new Runnable() {
         @Override
         public void run() {
@@ -74,6 +85,7 @@
             }
             if (DEBUG) Log.d(TAG, "PINNED_STACK:" + stackInfo);
             mState = STATE_PIP_OVERLAY;
+            mPipTaskId = stackInfo.taskIds[stackInfo.taskIds.length - 1];
             launchPipOverlayActivity();
         }
     };
@@ -86,15 +98,27 @@
         }
     };
 
-    private final BroadcastReceiver mPipButtonReceiver = new BroadcastReceiver() {
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (DEBUG) Log.d(TAG, "PIP button pressed");
-            if (!hasPipTasks()) {
-                startPip();
-            } else if (mState == STATE_PIP_OVERLAY) {
-                showPipMenu();
+            String action = intent.getAction();
+            if (Intent.ACTION_PICTURE_IN_PICTURE_BUTTON.equals(action)) {
+                if (DEBUG) Log.d(TAG, "PIP button pressed");
+                if (!hasPipTasks()) {
+                    startPip();
+                } else if (mState == STATE_PIP_OVERLAY) {
+                    showPipMenu();
+                }
+            } else if (Intent.ACTION_MEDIA_RESOURCE_GRANTED.equals(action)) {
+                String[] packageNames = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
+                int resourceType = intent.getIntExtra(Intent.EXTRA_MEDIA_RESOURCE_TYPE,
+                        INVALID_RESOURCE_TYPE);
+                if (mState != STATE_NO_PIP && packageNames != null && packageNames.length > 0
+                        && resourceType == Intent.EXTRA_MEDIA_RESOURCE_TYPE_VIDEO_CODEC) {
+                    handleMediaResourceGranted(packageNames);
+                }
             }
+
         }
     };
 
@@ -125,7 +149,8 @@
         }
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_PICTURE_IN_PICTURE_BUTTON);
-        mContext.registerReceiver(mPipButtonReceiver, intentFilter);
+        intentFilter.addAction(Intent.ACTION_MEDIA_RESOURCE_GRANTED);
+        mContext.registerReceiver(mBroadcastReceiver, intentFilter);
     }
 
     private void startPip() {
@@ -142,6 +167,7 @@
      */
     public void closePip() {
         mState = STATE_NO_PIP;
+        mPipTaskId = TASK_ID_NO_PIP;
         StackInfo stackInfo = null;
         try {
             stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
@@ -166,6 +192,7 @@
      */
     public void movePipToFullscreen() {
         mState = STATE_NO_PIP;
+        mPipTaskId = TASK_ID_NO_PIP;
         for (int i = mListeners.size() - 1; i >= 0; --i) {
             mListeners.get(i).onMoveToFullscreen();
         }
@@ -251,6 +278,45 @@
         }
     }
 
+    private void handleMediaResourceGranted(String[] packageNames) {
+        StackInfo fullscreenStack = null;
+        try {
+            fullscreenStack = mActivityManager.getStackInfo(FULLSCREEN_WORKSPACE_STACK_ID);
+        } catch (RemoteException e) {
+            Log.e(TAG, "getStackInfo failed", e);
+        }
+        if (fullscreenStack == null) {
+            return;
+        }
+        int fullscreenTopTaskId = fullscreenStack.taskIds[fullscreenStack.taskIds.length - 1];
+        List<RunningTaskInfo> tasks = null;
+        try {
+            tasks = mActivityManager.getTasks(MAX_RUNNING_TASKS_COUNT, 0);
+        } catch (RemoteException e) {
+            Log.e(TAG, "getTasks failed", e);
+        }
+        if (tasks == null) {
+            return;
+        }
+        boolean wasGrantedInFullscreen = false;
+        boolean wasGrantedInPip = false;
+        for (int i = tasks.size() - 1; i >= 0; --i) {
+            RunningTaskInfo task = tasks.get(i);
+            for (int j = packageNames.length - 1; j >= 0; --j) {
+                if (task.topActivity.getPackageName().equals(packageNames[j])) {
+                    if (task.id == fullscreenTopTaskId) {
+                        wasGrantedInFullscreen = true;
+                    } else if (task.id == mPipTaskId) {
+                        wasGrantedInPip= true;
+                    }
+                }
+            }
+        }
+        if (wasGrantedInFullscreen && !wasGrantedInPip) {
+            closePip();
+        }
+    }
+
     private class TaskStackListener extends ITaskStackListener.Stub {
         @Override
         public void onTaskStackChanged() throws RemoteException {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 28aeef7..dbbb189 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -2179,6 +2179,24 @@
             return true;
         }
 
+        @Override
+        public void disableSelf() {
+            synchronized(mLock) {
+                UserState userState = getUserStateLocked(mUserId);
+                if (userState.mEnabledServices.remove(mComponentName)) {
+                    final long identity = Binder.clearCallingIdentity();
+                    try {
+                        persistComponentNamesToSettingLocked(
+                                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+                                userState.mEnabledServices, mUserId);
+                    } finally {
+                        Binder.restoreCallingIdentity(identity);
+                    }
+                    onUserStateChangedLocked(userState);
+                }
+            }
+        }
+
         public boolean canReceiveEventsLocked() {
             return (mEventTypes != 0 && mFeedbackType != 0 && mService != null);
         }
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index aa15373..234c94e 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -27,9 +27,12 @@
 import android.app.backup.BackupAgent;
 import android.app.backup.BackupDataInput;
 import android.app.backup.BackupDataOutput;
+import android.app.backup.BackupManager;
+import android.app.backup.BackupProgress;
 import android.app.backup.BackupTransport;
 import android.app.backup.FullBackup;
 import android.app.backup.FullBackupDataOutput;
+import android.app.backup.IBackupObserver;
 import android.app.backup.RestoreDescription;
 import android.app.backup.RestoreSet;
 import android.app.backup.IBackupManager;
@@ -217,6 +220,7 @@
     private static final int MSG_RETRY_CLEAR = 12;
     private static final int MSG_WIDGET_BROADCAST = 13;
     private static final int MSG_RUN_FULL_TRANSPORT_BACKUP = 14;
+    private static final int MSG_REQUEST_BACKUP = 15;
 
     // backup task state machine tick
     static final int MSG_BACKUP_RESTORE_STEP = 20;
@@ -532,6 +536,25 @@
         }
     }
 
+    class BackupParams {
+        public IBackupTransport transport;
+        public String dirName;
+        public ArrayList<String> kvPackages;
+        public ArrayList<String> fullPackages;
+        public IBackupObserver observer;
+        public boolean userInitiated;
+
+        BackupParams(IBackupTransport transport, String dirName, ArrayList<String> kvPackages,
+                ArrayList<String> fullPackages, IBackupObserver observer, boolean userInitiated) {
+            this.transport = transport;
+            this.dirName = dirName;
+            this.kvPackages = kvPackages;
+            this.fullPackages = fullPackages;
+            this.observer = observer;
+            this.userInitiated = userInitiated;
+        }
+    }
+
     // Bookkeeping of in-flight operations for timeout etc. purposes.  The operation
     // token is the index of the entry in the pending-operations list.
     static final int OP_PENDING = 0;
@@ -719,7 +742,7 @@
                     try {
                         String dirName = transport.transportDirName();
                         PerformBackupTask pbt = new PerformBackupTask(transport, dirName,
-                                queue, oldJournal);
+                                queue, oldJournal, null, null, false);
                         Message pbtMessage = obtainMessage(MSG_BACKUP_RESTORE_STEP, pbt);
                         sendMessage(pbtMessage);
                     } catch (RemoteException e) {
@@ -942,6 +965,26 @@
                 mContext.sendBroadcastAsUser(intent, UserHandle.SYSTEM);
                 break;
             }
+
+            case MSG_REQUEST_BACKUP:
+            {
+                BackupParams params = (BackupParams)msg.obj;
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "MSG_REQUEST_BACKUP observer=" + params.observer);
+                }
+                ArrayList<BackupRequest> kvQueue = new ArrayList<>();
+                for (String packageName : params.kvPackages) {
+                    kvQueue.add(new BackupRequest(packageName));
+                }
+                mBackupRunning = true;
+                mWakelock.acquire();
+
+                PerformBackupTask pbt = new PerformBackupTask(params.transport, params.dirName,
+                    kvQueue, null, params.observer, params.fullPackages, true);
+                Message pbtMessage = obtainMessage(MSG_BACKUP_RESTORE_STEP, pbt);
+                sendMessage(pbtMessage);
+                break;
+            }
             }
         }
     }
@@ -2330,6 +2373,63 @@
         return token;
     }
 
+    public int requestBackup(String[] packages, IBackupObserver observer) {
+        mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "requestBackup");
+
+        if (packages == null || packages.length < 1) {
+            Slog.e(TAG, "No packages named for backup request");
+            sendBackupFinished(observer, BackupManager.ERROR_TRANSPORT_ABORTED);
+            throw new IllegalArgumentException("No packages are provided for backup");
+        }
+
+        IBackupTransport transport = getTransport(mCurrentTransport);
+        if (transport == null) {
+            sendBackupFinished(observer, BackupManager.ERROR_TRANSPORT_ABORTED);
+            return BackupManager.ERROR_TRANSPORT_ABORTED;
+        }
+
+        ArrayList<String> fullBackupList = new ArrayList<>();
+        ArrayList<String> kvBackupList = new ArrayList<>();
+        for (String packageName : packages) {
+            try {
+                PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName,
+                        PackageManager.GET_SIGNATURES);
+                if (!appIsEligibleForBackup(packageInfo.applicationInfo)) {
+                    sendBackupOnResult(observer, packageName,
+                            BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+                    continue;
+                }
+                if (appGetsFullBackup(packageInfo)) {
+                    fullBackupList.add(packageInfo.packageName);
+                } else {
+                    kvBackupList.add(packageInfo.packageName);
+                }
+            } catch (NameNotFoundException e) {
+                sendBackupOnResult(observer, packageName, BackupManager.ERROR_PACKAGE_NOT_FOUND);
+            }
+        }
+        EventLog.writeEvent(EventLogTags.BACKUP_REQUESTED, packages.length, kvBackupList.size(),
+                fullBackupList.size());
+        if (MORE_DEBUG) {
+            Slog.i(TAG, "Backup requested for " + packages.length + " packages, of them: " +
+                fullBackupList.size() + " full backups, " + kvBackupList.size() + " k/v backups");
+        }
+
+        String dirName;
+        try {
+            dirName = transport.transportDirName();
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Transport became unavailable while attempting backup");
+            sendBackupFinished(observer, BackupManager.ERROR_TRANSPORT_ABORTED);
+            return BackupManager.ERROR_TRANSPORT_ABORTED;
+        }
+        Message msg = mBackupHandler.obtainMessage(MSG_REQUEST_BACKUP);
+        msg.obj = new BackupParams(transport, dirName, kvBackupList, fullBackupList, observer,
+                true);
+        mBackupHandler.sendMessage(msg);
+        return BackupManager.SUCCESS;
+    }
+
     // -----
     // Interface and methods used by the asynchronous-with-timeout backup/restore operations
 
@@ -2429,6 +2529,8 @@
         File mStateDir;
         File mJournal;
         BackupState mCurrentState;
+        ArrayList<String> mPendingFullBackups;
+        IBackupObserver mObserver;
 
         // carried information about the current in-flight operation
         IBackupAgent mAgentBinder;
@@ -2441,12 +2543,17 @@
         ParcelFileDescriptor mNewState;
         int mStatus;
         boolean mFinished;
+        boolean mUserInitiated;
 
         public PerformBackupTask(IBackupTransport transport, String dirName,
-                ArrayList<BackupRequest> queue, File journal) {
+                ArrayList<BackupRequest> queue, File journal, IBackupObserver observer,
+                ArrayList<String> pendingFullBackups, boolean userInitiated) {
             mTransport = transport;
             mOriginalQueue = queue;
             mJournal = journal;
+            mObserver = observer;
+            mPendingFullBackups = pendingFullBackups;
+            mUserInitiated = userInitiated;
 
             mStateDir = new File(mBaseStateDir, dirName);
 
@@ -2498,9 +2605,10 @@
             mStatus = BackupTransport.TRANSPORT_OK;
 
             // Sanity check: if the queue is empty we have no work to do.
-            if (mOriginalQueue.isEmpty()) {
+            if (mOriginalQueue.isEmpty() && mPendingFullBackups.isEmpty()) {
                 Slog.w(TAG, "Backup begun with an empty queue - nothing to do.");
                 addBackupTrace("queue empty at begin");
+                sendBackupFinished(mObserver, BackupManager.SUCCESS);
                 executeNextState(BackupState.FINAL);
                 return;
             }
@@ -2584,6 +2692,8 @@
                     // if things went wrong at this point, we need to
                     // restage everything and try again later.
                     resetBackupState(mStateDir);  // Just to make sure.
+                    // In case of any other error, it's backup transport error.
+                    sendBackupFinished(mObserver, BackupManager.ERROR_TRANSPORT_ABORTED);
                     executeNextState(BackupState.FINAL);
                 }
             }
@@ -2625,6 +2735,10 @@
                     Slog.i(TAG, "Package " + request.packageName
                             + " no longer supports backup; skipping");
                     addBackupTrace("skipping - not eligible, completion is noop");
+                    // Shouldn't happen in case of requested backup, as pre-check was done in
+                    // #requestBackup(), except to app update done concurrently
+                    sendBackupOnResult(mObserver, mCurrentPackage.packageName,
+                        BackupManager.ERROR_BACKUP_NOT_ALLOWED);
                     executeNextState(BackupState.RUNNING_QUEUE);
                     return;
                 }
@@ -2636,6 +2750,10 @@
                     Slog.i(TAG, "Package " + request.packageName
                             + " requests full-data rather than key/value; skipping");
                     addBackupTrace("skipping - fullBackupOnly, completion is noop");
+                    // Shouldn't happen in case of requested backup, as pre-check was done in
+                    // #requestBackup()
+                    sendBackupOnResult(mObserver, mCurrentPackage.packageName,
+                        BackupManager.ERROR_BACKUP_NOT_ALLOWED);
                     executeNextState(BackupState.RUNNING_QUEUE);
                     return;
                 }
@@ -2645,6 +2763,8 @@
                     // and not yet launched out of that state, so just as it won't
                     // receive broadcasts, we won't run it for backup.
                     addBackupTrace("skipping - stopped");
+                    sendBackupOnResult(mObserver, mCurrentPackage.packageName,
+                        BackupManager.ERROR_BACKUP_NOT_ALLOWED);
                     executeNextState(BackupState.RUNNING_QUEUE);
                     return;
                 }
@@ -2692,10 +2812,14 @@
                         dataChangedImpl(request.packageName);
                         mStatus = BackupTransport.TRANSPORT_OK;
                         if (mQueue.isEmpty()) nextState = BackupState.FINAL;
+                        sendBackupOnResult(mObserver, mCurrentPackage.packageName,
+                            BackupManager.ERROR_AGENT_FAILURE);
                     } else if (mStatus == BackupTransport.AGENT_UNKNOWN) {
                         // Failed lookup of the app, so we couldn't bring up an agent, but
                         // we're otherwise fine.  Just drop it and go on to the next as usual.
                         mStatus = BackupTransport.TRANSPORT_OK;
+                        sendBackupOnResult(mObserver, mCurrentPackage.packageName,
+                            BackupManager.ERROR_PACKAGE_NOT_FOUND);
                     } else {
                         // Transport-level failure means we reenqueue everything
                         revertAndEndBackup();
@@ -2750,9 +2874,37 @@
                 }
             }
 
-            // Only once we're entirely finished do we release the wakelock
             clearBackupTrace();
-            Slog.i(BackupManagerService.TAG, "Backup pass finished.");
+
+            if (mStatus == BackupTransport.TRANSPORT_OK &&
+                    mPendingFullBackups != null && !mPendingFullBackups.isEmpty()) {
+                Slog.d(TAG, "Starting full backups for: " + mPendingFullBackups);
+                CountDownLatch latch = new CountDownLatch(1);
+                String[] fullBackups =
+                        mPendingFullBackups.toArray(new String[mPendingFullBackups.size()]);
+                PerformFullTransportBackupTask task =
+                        new PerformFullTransportBackupTask(/*fullBackupRestoreObserver*/ null,
+                                fullBackups, /*updateSchedule*/ false, /*runningJob*/ null, latch,
+                                mObserver, mUserInitiated);
+                // Acquiring wakelock for PerformFullTransportBackupTask before its start.
+                mWakelock.acquire();
+                (new Thread(task, "full-transport-requested")).start();
+            } else {
+                switch (mStatus) {
+                    case BackupTransport.TRANSPORT_OK:
+                        sendBackupFinished(mObserver, BackupManager.SUCCESS);
+                        break;
+                    case BackupTransport.TRANSPORT_NOT_INITIALIZED:
+                        sendBackupFinished(mObserver, BackupManager.ERROR_TRANSPORT_ABORTED);
+                        break;
+                    case BackupTransport.TRANSPORT_ERROR:
+                    default:
+                        sendBackupFinished(mObserver, BackupManager.ERROR_TRANSPORT_ABORTED);
+                        break;
+                }
+            }
+            Slog.i(BackupManagerService.TAG, "K/V backup pass finished.");
+            // Only once we're entirely finished do we release the wakelock for k/v backup.
             mWakelock.release();
         }
 
@@ -2959,6 +3111,8 @@
                                 EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, pkgName,
                                         "bad key");
                                 mBackupHandler.removeMessages(MSG_TIMEOUT);
+                                sendBackupOnResult(mObserver, pkgName,
+                                        BackupManager.ERROR_AGENT_FAILURE);
                                 agentErrorCleanup();
                                 // agentErrorCleanup() implicitly executes next state properly
                                 return;
@@ -3003,7 +3157,8 @@
                         backupData = ParcelFileDescriptor.open(mBackupDataName,
                                 ParcelFileDescriptor.MODE_READ_ONLY);
                         addBackupTrace("sending data to transport");
-                        mStatus = mTransport.performBackup(mCurrentPackage, backupData);
+                        int flags = mUserInitiated ? BackupTransport.FLAG_USER_INITIATED : 0;
+                        mStatus = mTransport.performBackup(mCurrentPackage, backupData, flags);
                     }
 
                     // TODO - We call finishBackup() for each application backed up, because
@@ -3030,6 +3185,7 @@
                     // with the new state file it just created.
                     mBackupDataName.delete();
                     mNewStateName.renameTo(mSavedStateName);
+                    sendBackupOnResult(mObserver, pkgName, BackupManager.SUCCESS);
                     EventLog.writeEvent(EventLogTags.BACKUP_PACKAGE, pkgName, size);
                     logBackupComplete(pkgName);
                 } else if (mStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
@@ -3037,12 +3193,16 @@
                     // back but proceed with running the rest of the queue.
                     mBackupDataName.delete();
                     mNewStateName.delete();
+                    sendBackupOnResult(mObserver, pkgName,
+                            BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
                     EventLogTags.writeBackupAgentFailure(pkgName, "Transport rejected");
                 } else {
                     // Actual transport-level failure to communicate the data to the backend
+                    sendBackupOnResult(mObserver, pkgName, BackupManager.ERROR_TRANSPORT_ABORTED);
                     EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, pkgName);
                 }
             } catch (Exception e) {
+                sendBackupOnResult(mObserver, pkgName, BackupManager.ERROR_TRANSPORT_ABORTED);
                 Slog.e(TAG, "Transport error backing up " + pkgName, e);
                 EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, pkgName);
                 mStatus = BackupTransport.TRANSPORT_ERROR;
@@ -3290,6 +3450,8 @@
          *         or one of the other BackupTransport.* error codes as appropriate
          */
         int preflightFullBackup(PackageInfo pkg, IBackupAgent agent);
+
+        long expectedSize();
     };
 
     class FullBackupEngine {
@@ -3997,16 +4159,21 @@
         CountDownLatch mLatch;
         AtomicBoolean mKeepRunning;     // signal from job scheduler
         FullBackupJob mJob;             // if a scheduled job needs to be finished afterwards
+        IBackupObserver mBackupObserver;
+        boolean mUserInitiated;
 
         PerformFullTransportBackupTask(IFullBackupRestoreObserver observer, 
                 String[] whichPackages, boolean updateSchedule,
-                FullBackupJob runningJob, CountDownLatch latch) {
+                FullBackupJob runningJob, CountDownLatch latch, IBackupObserver backupObserver,
+                boolean userInitiated) {
             super(observer);
             mUpdateSchedule = updateSchedule;
             mLatch = latch;
             mKeepRunning = new AtomicBoolean(true);
             mJob = runningJob;
             mPackages = new ArrayList<PackageInfo>(whichPackages.length);
+            mBackupObserver = backupObserver;
+            mUserInitiated = userInitiated;
 
             for (String pkg : whichPackages) {
                 try {
@@ -4020,6 +4187,8 @@
                         if (MORE_DEBUG) {
                             Slog.d(TAG, "Ignoring opted-out package " + pkg);
                         }
+                        sendBackupOnResult(mBackupObserver, pkg,
+                                BackupManager.ERROR_BACKUP_NOT_ALLOWED);
                         continue;
                     } else if ((info.applicationInfo.uid < Process.FIRST_APPLICATION_UID)
                             && (info.applicationInfo.backupAgentName == null)) {
@@ -4028,6 +4197,8 @@
                         if (MORE_DEBUG) {
                             Slog.d(TAG, "Ignoring non-agent system package " + pkg);
                         }
+                        sendBackupOnResult(mBackupObserver, pkg,
+                                BackupManager.ERROR_BACKUP_NOT_ALLOWED);
                         continue;
                     } else if ((info.applicationInfo.flags & ApplicationInfo.FLAG_STOPPED) != 0) {
                         // Cull any packages in the 'stopped' state: they've either just been
@@ -4036,6 +4207,8 @@
                         if (MORE_DEBUG) {
                             Slog.d(TAG, "Ignoring stopped package " + pkg);
                         }
+                        sendBackupOnResult(mBackupObserver, pkg,
+                                BackupManager.ERROR_BACKUP_NOT_ALLOWED);
                         continue;
                     }
                     mPackages.add(info);
@@ -4068,17 +4241,20 @@
                                 + " p=" + mProvisioned + "; ignoring");
                     }
                     mUpdateSchedule = false;
+                    sendBackupFinished(mBackupObserver, BackupManager.ERROR_BACKUP_NOT_ALLOWED);
                     return;
                 }
 
                 IBackupTransport transport = getTransport(mCurrentTransport);
                 if (transport == null) {
                     Slog.w(TAG, "Transport not present; full data backup not performed");
+                    sendBackupFinished(mBackupObserver, BackupManager.ERROR_TRANSPORT_ABORTED);
                     return;
                 }
 
                 // Set up to send data to the transport
                 final int N = mPackages.size();
+                final byte[] buffer = new byte[8192];
                 for (int i = 0; i < N; i++) {
                     currentPackage = mPackages.get(i);
                     if (DEBUG) {
@@ -4091,8 +4267,9 @@
                     transportPipes = ParcelFileDescriptor.createPipe();
 
                     // Tell the transport the data's coming
+                    int flags = mUserInitiated ? BackupTransport.FLAG_USER_INITIATED : 0;
                     int result = transport.performFullBackup(currentPackage,
-                            transportPipes[0]);
+                            transportPipes[0], flags);
                     if (result == BackupTransport.TRANSPORT_OK) {
                         // The transport has its own copy of the read end of the pipe,
                         // so close ours now
@@ -4119,7 +4296,13 @@
                                 enginePipes[0].getFileDescriptor());
                         FileOutputStream out = new FileOutputStream(
                                 transportPipes[1].getFileDescriptor());
-                        byte[] buffer = new byte[8192];
+                        long totalRead = 0;
+                        final long expectedSize = backupRunner.expectedSize();
+                        if (expectedSize < 0) {
+                            result = BackupTransport.AGENT_ERROR;
+                            sendBackupOnResult(mBackupObserver, currentPackage.packageName,
+                                    BackupManager.ERROR_AGENT_FAILURE);
+                        }
                         int nRead = 0;
                         do {
                             if (!mKeepRunning.get()) {
@@ -4135,6 +4318,11 @@
                             if (nRead > 0) {
                                 out.write(buffer, 0, nRead);
                                 result = transport.sendBackupData(nRead);
+                                totalRead += nRead;
+                                if (mBackupObserver != null && expectedSize > 0) {
+                                    sendBackupOnUpdate(mBackupObserver, currentPackage.packageName,
+                                        new BackupProgress(expectedSize, totalRead));
+                                }
                             }
                         } while (nRead > 0 && result == BackupTransport.TRANSPORT_OK);
 
@@ -4188,16 +4376,22 @@
                         }
                         EventLog.writeEvent(EventLogTags.FULL_BACKUP_AGENT_FAILURE,
                                 currentPackage.packageName, "transport rejected");
+                        sendBackupOnResult(mBackupObserver, currentPackage.packageName,
+                            BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
                         // do nothing, clean up, and continue looping
                     } else if (result != BackupTransport.TRANSPORT_OK) {
                         Slog.w(TAG, "Transport failed; aborting backup: " + result);
                         EventLog.writeEvent(EventLogTags.FULL_BACKUP_TRANSPORT_FAILURE);
+                        sendBackupOnResult(mBackupObserver, currentPackage.packageName,
+                            BackupManager.ERROR_TRANSPORT_ABORTED);
                         return;
                     } else {
                         // Success!
                         EventLog.writeEvent(EventLogTags.FULL_BACKUP_SUCCESS,
                                 currentPackage.packageName);
                         logBackupComplete(currentPackage.packageName);
+                        sendBackupOnResult(mBackupObserver, currentPackage.packageName,
+                            BackupManager.SUCCESS);
                     }
                     cleanUpPipes(transportPipes);
                     cleanUpPipes(enginePipes);
@@ -4207,8 +4401,10 @@
                 if (DEBUG) {
                     Slog.i(TAG, "Full backup completed.");
                 }
+                sendBackupFinished(mBackupObserver, BackupManager.SUCCESS);
             } catch (Exception e) {
                 Slog.w(TAG, "Exception trying full transport backup", e);
+                sendBackupFinished(mBackupObserver, BackupManager.ERROR_TRANSPORT_ABORTED);
             } finally {
                 cleanUpPipes(transportPipes);
                 cleanUpPipes(enginePipes);
@@ -4221,6 +4417,7 @@
                     mRunningFullBackupTask = null;
                 }
 
+
                 mLatch.countDown();
 
                 // Now that we're actually done with schedule-driven work, reschedule
@@ -4228,6 +4425,8 @@
                 if (mUpdateSchedule) {
                     scheduleNextFullBackupJob(backoff);
                 }
+                Slog.i(BackupManagerService.TAG, "Full data backup pass finished.");
+                mWakelock.release();
             }
         }
 
@@ -4316,7 +4515,16 @@
                 mResult.set(BackupTransport.AGENT_ERROR);
                 mLatch.countDown();
             }
-            
+
+            @Override
+            public long expectedSize() {
+                try {
+                    mLatch.await();
+                    return mResult.get();
+                } catch (InterruptedException e) {
+                    return BackupTransport.NO_MORE_DATA;
+                }
+            }
         }
 
         class SinglePackageBackupRunner implements Runnable {
@@ -4351,6 +4559,10 @@
                     }
                 }
             }
+
+            long expectedSize() {
+                return mPreflight.expectedSize();
+            }
         }
     }
 
@@ -4586,7 +4798,9 @@
             CountDownLatch latch = new CountDownLatch(1);
             String[] pkg = new String[] {entry.packageName};
             mRunningFullBackupTask = new PerformFullTransportBackupTask(null, pkg, true,
-                    scheduledJob, latch);
+                    scheduledJob, latch, null, false /* userInitiated */);
+            // Acquiring wakelock for PerformFullTransportBackupTask before its start.
+            mWakelock.acquire();
             (new Thread(mRunningFullBackupTask)).start();
         }
 
@@ -8744,8 +8958,10 @@
             }
 
             CountDownLatch latch = new CountDownLatch(1);
-            PerformFullTransportBackupTask task =
-                    new PerformFullTransportBackupTask(null, pkgNames, false, null, latch);
+            PerformFullTransportBackupTask task = new PerformFullTransportBackupTask(null, pkgNames,
+                    false, null, latch, null, false /* userInitiated */);
+            // Acquiring wakelock for PerformFullTransportBackupTask before its start.
+            mWakelock.acquire();
             (new Thread(task, "full-transport-master")).start();
             do {
                 try {
@@ -9769,4 +9985,42 @@
             }
         }
     }
+
+    private static void sendBackupOnUpdate(IBackupObserver observer, String packageName,
+            BackupProgress progress) {
+        if (observer != null) {
+            try {
+                observer.onUpdate(packageName, progress);
+            } catch (RemoteException e) {
+                if (DEBUG) {
+                    Slog.w(TAG, "Backup observer went away: onUpdate");
+                }
+            }
+        }
+    }
+
+    private static void sendBackupOnResult(IBackupObserver observer, String packageName,
+            int status) {
+        if (observer != null) {
+            try {
+                observer.onResult(packageName, status);
+            } catch (RemoteException e) {
+                if (DEBUG) {
+                    Slog.w(TAG, "Backup observer went away: onResult");
+                }
+            }
+        }
+    }
+
+    private static void sendBackupFinished(IBackupObserver observer, int status) {
+        if (observer != null) {
+            try {
+                observer.backupFinished(status);
+            } catch (RemoteException e) {
+                if (DEBUG) {
+                    Slog.w(TAG, "Backup observer went away: backupFinished");
+                }
+            }
+        }
+    }
 }
diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java
index a51ab55..505a1a5 100644
--- a/services/backup/java/com/android/server/backup/Trampoline.java
+++ b/services/backup/java/com/android/server/backup/Trampoline.java
@@ -17,6 +17,7 @@
 package com.android.server.backup;
 
 import android.app.backup.IBackupManager;
+import android.app.backup.IBackupObserver;
 import android.app.backup.IFullBackupRestoreObserver;
 import android.app.backup.IRestoreSession;
 import android.content.Context;
@@ -325,6 +326,12 @@
     }
 
     @Override
+    public int requestBackup(String[] packages, IBackupObserver observer) throws RemoteException {
+        BackupManagerService svc = mService;
+        return (svc != null) ? svc.requestBackup(packages, observer) : null;
+    }
+
+    @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
 
diff --git a/services/core/java/com/android/server/AssetAtlasService.java b/services/core/java/com/android/server/AssetAtlasService.java
index b5ea641..b0f6048 100644
--- a/services/core/java/com/android/server/AssetAtlasService.java
+++ b/services/core/java/com/android/server/AssetAtlasService.java
@@ -79,7 +79,7 @@
     private static final boolean DEBUG_ATLAS_TEXTURE = false;
 
     // Minimum size in pixels to consider for the resulting texture
-    private static final int MIN_SIZE = 768;
+    private static final int MIN_SIZE = 512;
     // Maximum size in pixels to consider for the resulting texture
     private static final int MAX_SIZE = 2048;
     // Increment in number of pixels between size variants when looking
@@ -665,22 +665,32 @@
             if (DEBUG_ATLAS) Log.d(LOG_TAG, "Running " + Thread.currentThread().getName());
 
             Atlas.Entry entry = new Atlas.Entry();
-            for (Atlas.Type type : Atlas.Type.values()) {
-                for (int width = mEnd; width > mStart; width -= mStep) {
-                    for (int height = MAX_SIZE; height > MIN_SIZE; height -= STEP) {
-                        // If the atlas is not big enough, skip it
-                        if (width * height <= mThreshold) continue;
 
+            for (int width = mEnd; width > mStart; width -= mStep) {
+                for (int height = MAX_SIZE; height > MIN_SIZE; height -= STEP) {
+                    // If the atlas is not big enough, skip it
+                    if (width * height <= mThreshold) continue;
+
+                    boolean packSuccess = false;
+
+                    for (Atlas.Type type : Atlas.Type.values()) {
                         final int count = packBitmaps(type, width, height, entry);
                         if (count > 0) {
                             mResults.add(new WorkerResult(type, width, height, count));
-                            // If we were able to pack everything let's stop here
-                            // Increasing the height further won't make things better
                             if (count == mBitmaps.size()) {
+                                // If we were able to pack everything let's stop here
+                                // Changing the type further won't make things better
+                                packSuccess = true;
                                 break;
                             }
                         }
                     }
+
+                    // If we were not able to pack everything let's stop here
+                    // Decreasing the height further won't make things better
+                    if (!packSuccess) {
+                        break;
+                    }
                 }
             }
 
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 58a0356..9bd79c9 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -936,13 +936,23 @@
         @Override public void addPowerSaveWhitelistApp(String name) {
             getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
                     null);
-            addPowerSaveWhitelistAppInternal(name);
+            long ident = Binder.clearCallingIdentity();
+            try {
+                addPowerSaveWhitelistAppInternal(name);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
         }
 
         @Override public void removePowerSaveWhitelistApp(String name) {
             getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
                     null);
-            removePowerSaveWhitelistAppInternal(name);
+            long ident = Binder.clearCallingIdentity();
+            try {
+                removePowerSaveWhitelistAppInternal(name);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
         }
 
         @Override public String[] getSystemPowerWhitelistExceptIdle() {
@@ -1003,19 +1013,34 @@
         @Override public void exitIdle(String reason) {
             getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER,
                     null);
-            exitIdleInternal(reason);
+            long ident = Binder.clearCallingIdentity();
+            try {
+                exitIdleInternal(reason);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
         }
 
         @Override public void downloadServiceActive(IBinder token) {
             getContext().enforceCallingOrSelfPermission(
                     "android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS", null);
-            DeviceIdleController.this.downloadServiceActive(token);
+            long ident = Binder.clearCallingIdentity();
+            try {
+                DeviceIdleController.this.downloadServiceActive(token);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
         }
 
         @Override public void downloadServiceInactive() {
             getContext().enforceCallingOrSelfPermission(
                     "android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS", null);
-            DeviceIdleController.this.downloadServiceInactive();
+            long ident = Binder.clearCallingIdentity();
+            try {
+                DeviceIdleController.this.downloadServiceInactive();
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
         }
 
         @Override public boolean registerMaintenanceActivityListener(
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index 516e2f4..7bf1dea 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -107,6 +107,7 @@
 2825 backup_success (Packages|1|1),(Time|1|3)
 2826 backup_reset (Transport|3)
 2827 backup_initialize
+2828 backup_requested (Total|1|1),(Key-Value|1|1),(Full|1|1)
 2830 restore_start (Transport|3),(Source|2|5)
 2831 restore_transport_failure
 2832 restore_agent_failure (Package|3),(Message|3)
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index d3fed6d..798a04a 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -450,6 +450,7 @@
     private boolean mShowImeWithHardKeyboard;
     private final MyPackageMonitor mMyPackageMonitor = new MyPackageMonitor();
     private final IPackageManager mIPackageManager;
+    private final String mSlotIme;
 
     class SettingsObserver extends ContentObserver {
         int mUserId;
@@ -761,6 +762,7 @@
         mHardKeyboardListener = new HardKeyboardListener();
         mHasFeature = context.getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_INPUT_METHODS);
+        mSlotIme = mContext.getString(com.android.internal.R.string.status_bar_ime);
 
         Bundle extras = new Bundle();
         extras.putBoolean(Notification.EXTRA_ALLOW_DURING_SETUP, true);
@@ -1043,7 +1045,7 @@
                 mNotificationManager = (NotificationManager)
                         mContext.getSystemService(Context.NOTIFICATION_SERVICE);
                 mStatusBar = statusBar;
-                statusBar.setIconVisibility("ime", false);
+                statusBar.setIconVisibility(mSlotIme, false);
                 updateSystemUiLocked(mCurToken, mImeWindowVis, mBackDisposition);
                 mShowOngoingImeSwitcherForPhones = mRes.getBoolean(
                         com.android.internal.R.bool.show_ongoing_ime_switcher);
@@ -1595,7 +1597,7 @@
             mCurMethod = null;
         }
         if (mStatusBar != null) {
-            mStatusBar.setIconVisibility("ime", false);
+            mStatusBar.setIconVisibility(mSlotIme, false);
         }
     }
 
@@ -1635,7 +1637,7 @@
                 if (iconId == 0) {
                     if (DEBUG) Slog.d(TAG, "hide the small icon for the input method");
                     if (mStatusBar != null) {
-                        mStatusBar.setIconVisibility("ime", false);
+                        mStatusBar.setIconVisibility(mSlotIme, false);
                     }
                 } else if (packageName != null) {
                     if (DEBUG) Slog.d(TAG, "show a small icon for the input method");
@@ -1650,10 +1652,10 @@
                         /* ignore */
                     }
                     if (mStatusBar != null) {
-                        mStatusBar.setIcon("ime", packageName, iconId, 0,
+                        mStatusBar.setIcon(mSlotIme, packageName, iconId, 0,
                                 contentDescription  != null
                                         ? contentDescription.toString() : null);
-                        mStatusBar.setIconVisibility("ime", true);
+                        mStatusBar.setIconVisibility(mSlotIme, true);
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 0f12818..b86b3fd 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -176,6 +176,7 @@
     private static final String[] ACCOUNT_TYPE_COUNT_PROJECTION =
             new String[] { ACCOUNTS_TYPE, ACCOUNTS_TYPE_COUNT};
     private static final Intent ACCOUNTS_CHANGED_INTENT;
+
     static {
         ACCOUNTS_CHANGED_INTENT = new Intent(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION);
         ACCOUNTS_CHANGED_INTENT.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
@@ -2491,7 +2492,7 @@
             Bundle appInfo) {
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.v(TAG,
-                    "finishSession: response "+ response
+                    "finishSession: response " + response
                             + ", expectActivityLaunch " + expectActivityLaunch
                             + ", caller's uid " + Binder.getCallingUid()
                             + ", pid " + Binder.getCallingPid());
@@ -2778,6 +2779,99 @@
     }
 
     @Override
+    public void isCredentialsUpdateSuggested(
+            IAccountManagerResponse response,
+            final Account account,
+            final String statusToken) {
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG,
+                    "isCredentialsUpdateSuggested: " + account + ", response " + response
+                            + ", caller's uid " + Binder.getCallingUid()
+                            + ", pid " + Binder.getCallingPid());
+        }
+        if (response == null) {
+            throw new IllegalArgumentException("response is null");
+        }
+        if (account == null) {
+            throw new IllegalArgumentException("account is null");
+        }
+        if (TextUtils.isEmpty(statusToken)) {
+            throw new IllegalArgumentException("status token is empty");
+        }
+
+        int uid = Binder.getCallingUid();
+        // Only allow system to start session
+        if (!isSystemUid(uid)) {
+            String msg = String.format(
+                    "uid %s cannot stat add account session.",
+                    uid);
+            throw new SecurityException(msg);
+        }
+
+        int usrId = UserHandle.getCallingUserId();
+        long identityToken = clearCallingIdentity();
+        try {
+            UserAccounts accounts = getUserAccounts(usrId);
+            new Session(accounts, response, account.type, false /* expectActivityLaunch */,
+                    false /* stripAuthTokenFromResult */, account.name,
+                    false /* authDetailsRequired */) {
+                @Override
+                protected String toDebugString(long now) {
+                    return super.toDebugString(now) + ", isCredentialsUpdateSuggested"
+                            + ", " + account;
+                }
+
+                @Override
+                public void run() throws RemoteException {
+                    mAuthenticator.isCredentialsUpdateSuggested(this, account, statusToken);
+                }
+
+                @Override
+                public void onResult(Bundle result) {
+                    IAccountManagerResponse response = getResponseAndClose();
+                    if (response == null) {
+                        return;
+                    }
+
+                    if (result == null) {
+                        sendErrorResponse(
+                                response,
+                                AccountManager.ERROR_CODE_INVALID_RESPONSE,
+                                "null bundle");
+                        return;
+                    }
+
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG, getClass().getSimpleName() + " calling onResult() on response "
+                                + response);
+                    }
+                    // Check to see if an error occurred. We know if an error occurred because all
+                    // error codes are greater than 0.
+                    if ((result.getInt(AccountManager.KEY_ERROR_CODE, -1) > 0)) {
+                        sendErrorResponse(response,
+                                result.getInt(AccountManager.KEY_ERROR_CODE),
+                                result.getString(AccountManager.KEY_ERROR_MESSAGE));
+                        return;
+                    }
+                    if (!result.containsKey(AccountManager.KEY_BOOLEAN_RESULT)) {
+                        sendErrorResponse(
+                                response,
+                                AccountManager.ERROR_CODE_INVALID_RESPONSE,
+                                "no result in response");
+                        return;
+                    }
+                    final Bundle newResult = new Bundle();
+                    newResult.putBoolean(AccountManager.KEY_BOOLEAN_RESULT,
+                            result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false));
+                    sendResponse(response, newResult);
+                }
+            }.bind();
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+    }
+
+    @Override
     public void editProperties(IAccountManagerResponse response, final String accountType,
             final boolean expectActivityLaunch) {
         final int callingUid = Binder.getCallingUid();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index ca33f9f..adb11a4 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1475,6 +1475,7 @@
     final ServiceThread mHandlerThread;
     final MainHandler mHandler;
     final UiHandler mUiHandler;
+    final ProcessStartLogger mProcessStartLogger;
 
     PackageManagerInternal mPackageManagerInt;
 
@@ -2452,6 +2453,8 @@
         mHandler = new MainHandler(mHandlerThread.getLooper());
         mUiHandler = new UiHandler();
 
+        mProcessStartLogger = new ProcessStartLogger();
+
         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
                 "foreground", BROADCAST_FG_TIMEOUT, false);
         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
@@ -3552,6 +3555,8 @@
                     app.processName, hostingType,
                     hostingNameStr != null ? hostingNameStr : "");
 
+            mProcessStartLogger.logIfNeededLocked(app, startResult);
+
             if (app.persistent) {
                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
             }
@@ -6634,6 +6639,8 @@
             }
         }, dumpheapFilter);
 
+        mProcessStartLogger.registerListener(mContext);
+
         // Let system services know.
         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
 
@@ -21136,7 +21143,12 @@
         public void moveToFront() {
             checkCaller();
             // Will bring task to front if it already has a root activity.
-            startActivityFromRecentsInner(mTaskId, null);
+            final long origId = Binder.clearCallingIdentity();
+            try {
+                startActivityFromRecentsInner(mTaskId, null);
+            } finally {
+                Binder.restoreCallingIdentity(origId);
+            }
         }
 
         @Override
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 3d16141..e3f4999 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -41,7 +41,6 @@
 import android.graphics.Rect;
 import android.util.ArraySet;
 
-import android.util.Log;
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.content.ReferrerIntent;
 import com.android.internal.os.BatteryStatsImpl;
@@ -4713,7 +4712,6 @@
         }
 
         task.stack = null;
-        task.lastStackClear = Log.getStackTraceString(new Throwable());
     }
 
     TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 280ab60..1fc674b 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1719,11 +1719,17 @@
                     // moveTaskToStackUncheckedLocked() should already placed the task on top,
                     // still need moveTaskToFrontLocked() below for any transition settings.
                 }
-                // WM resizeTask must be done after the task is moved to the correct stack,
-                // because Task's setBounds() also updates dim layer's bounds, but that has
-                // dependency on the stack.
-                mWindowManager.resizeTask(task.taskId, bounds, task.mOverrideConfig,
-                        false /*relayout*/, false /*forced*/);
+                if (StackId.resizeStackWithLaunchBounds(stackId)) {
+                    resizeStackLocked(stackId, bounds,
+                            null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
+                            !PRESERVE_WINDOWS, true /* allowResizeInDockedMode */);
+                } else {
+                    // WM resizeTask must be done after the task is moved to the correct stack,
+                    // because Task's setBounds() also updates dim layer's bounds, but that has
+                    // dependency on the stack.
+                    mWindowManager.resizeTask(task.taskId, bounds, task.mOverrideConfig,
+                            false /* relayout */, false /* forced */);
+                }
             }
         }
 
@@ -2245,7 +2251,10 @@
             // If we didn't actual do a relaunch (indicated by kept==true meaning we kept the old
             // window), we need to clear the replace window settings. Otherwise, we schedule a
             // timeout to remove the old window if the replacing window is not coming in time.
-            mWindowManager.scheduleClearReplacingWindowIfNeeded(topActivity.appToken, !kept);
+            // In case of the pinned stack we don't resize the task during the move, but we will
+            // resize the stack soon after so we want to retain the replacing window.
+            mWindowManager.scheduleClearReplacingWindowIfNeeded(topActivity.appToken,
+                    !kept || stackId == PINNED_STACK_ID);
         }
 
         // The task might have already been running and its visibility needs to be synchronized with
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index cfef431..d847824 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -5,6 +5,7 @@
 import static android.app.ActivityManager.START_CLASS_NOT_FOUND;
 import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
 import static android.app.ActivityManager.START_FLAG_ONLY_IF_NEEDED;
+import static android.app.ActivityManager.START_PERMISSION_DENIED;
 import static android.app.ActivityManager.START_RETURN_INTENT_TO_CALLER;
 import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
 import static android.app.ActivityManager.START_SUCCESS;
@@ -42,6 +43,7 @@
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
+import static android.content.pm.ApplicationInfo.FLAG_SUSPENDED;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
@@ -64,6 +66,7 @@
 import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
+import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
 import static com.android.server.am.ActivityStackSupervisor.TAG_TASKS;
 import static com.android.server.am.EventLogTags.AM_NEW_INTENT;
 
@@ -227,6 +230,17 @@
             }
         }
 
+        if (aInfo != null) {
+            if ((aInfo.applicationInfo.flags & FLAG_SUSPENDED) != 0) {
+                Slog.w(TAG, "Application \"" + aInfo.applicationInfo.packageName
+                        + "\" is suspended. Refusing to start: " + intent.toString());
+                // TODO: show a dialog/activity informing the user that the application is suspended 
+                // and redirect the launch to it. Do not return START_PERMISSION_DENIED because 
+                // it is wrong.
+                err = ActivityManager.START_PERMISSION_DENIED;
+            }
+        }
+
         final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
 
         if (err == ActivityManager.START_SUCCESS) {
@@ -1281,10 +1295,6 @@
     }
 
     private ActivityRecord setTargetStackAndMoveToFrontIfNeeded(ActivityRecord intentActivity) {
-        if (intentActivity.task.stack == null) {
-            Slog.wtf(TAG, "Oops, the stack is null, we are about to crash. It was last cleared: "
-                    + intentActivity.task.lastStackClear);
-        }
         mTargetStack = intentActivity.task.stack;
         mTargetStack.mLastPausedActivity = null;
         // If the target task is not in the front, then we need to bring it to the front...
@@ -1433,7 +1443,14 @@
                     mVoiceSession, mVoiceInteractor, !mLaunchTaskBehind /* toTop */);
             mStartActivity.setTask(task, taskToAffiliate);
             if (mLaunchBounds != null) {
-                mStartActivity.task.updateOverrideConfiguration(mLaunchBounds);
+                final int stackId = mTargetStack.mStackId;
+                if (StackId.resizeStackWithLaunchBounds(stackId)) {
+                    mSupervisor.resizeStackLocked(stackId, mLaunchBounds,
+                            null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
+                            !PRESERVE_WINDOWS, true /* allowResizeInDockedMode */);
+                } else {
+                    mStartActivity.task.updateOverrideConfiguration(mLaunchBounds);
+                }
             }
             if (DEBUG_TASKS) Slog.v(TAG_TASKS,
                     "Starting new activity " +
@@ -1516,6 +1533,11 @@
                 mSupervisor.moveTaskToStackUncheckedLocked(
                         mInTask, stackId, ON_TOP, !FORCE_FOCUS, "inTaskToFront");
             }
+            if (StackId.resizeStackWithLaunchBounds(stackId)) {
+                mSupervisor.resizeStackLocked(stackId, mLaunchBounds,
+                        null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
+                        !PRESERVE_WINDOWS, true /* allowResizeInDockedMode */);
+            }
         }
         mTargetStack = mInTask.stack;
         mTargetStack.moveTaskToFrontLocked(
diff --git a/services/core/java/com/android/server/am/ProcessStartLogger.java b/services/core/java/com/android/server/am/ProcessStartLogger.java
new file mode 100644
index 0000000..d2aa966
--- /dev/null
+++ b/services/core/java/com/android/server/am/ProcessStartLogger.java
@@ -0,0 +1,151 @@
+package com.android.server.am;
+
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+
+import android.app.AppGlobals;
+import android.auditing.SecurityLog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.Process.ProcessStartResult;
+import android.util.Slog;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+
+/**
+ * A class that logs process start information (including APK hash) to the security log.
+ */
+class ProcessStartLogger {
+    private static final String CLASS_NAME = "ProcessStartLogger";
+    private static final String TAG = TAG_WITH_CLASS_NAME ? CLASS_NAME : TAG_AM;
+
+    final HandlerThread mHandlerProcessLoggingThread;
+    Handler mHandlerProcessLogging;
+    // Should only access in mHandlerProcessLoggingThread
+    final HashMap<String, String> mProcessLoggingApkHashes;
+
+    ProcessStartLogger() {
+        mHandlerProcessLoggingThread = new HandlerThread(CLASS_NAME,
+                Process.THREAD_PRIORITY_BACKGROUND);
+        mProcessLoggingApkHashes = new HashMap();
+    }
+
+    void logIfNeededLocked(ProcessRecord app, ProcessStartResult startResult) {
+        if (!SecurityLog.isLoggingEnabled()) {
+            return;
+        }
+        if (!mHandlerProcessLoggingThread.isAlive()) {
+            mHandlerProcessLoggingThread.start();
+            mHandlerProcessLogging = new Handler(mHandlerProcessLoggingThread.getLooper());
+        }
+        mHandlerProcessLogging.post(new ProcessLoggingRunnable(app, startResult,
+                System.currentTimeMillis()));
+    }
+
+    void registerListener(Context context) {
+        IntentFilter packageChangedFilter = new IntentFilter();
+        packageChangedFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        packageChangedFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+        context.registerReceiver(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)
+                        || Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
+                    int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
+                            getSendingUserId());
+                    String packageName = intent.getData().getSchemeSpecificPart();
+                    try {
+                        ApplicationInfo info = AppGlobals.getPackageManager().getApplicationInfo(
+                                packageName, 0, userHandle);
+                        invaildateCache(info.sourceDir);
+                    } catch (RemoteException e) {
+                    }
+                }
+            }
+        }, packageChangedFilter);
+    }
+
+    private void invaildateCache(final String apkPath) {
+        if (mHandlerProcessLogging != null) {
+            mHandlerProcessLogging.post(new Runnable() {
+                @Override
+                public void run() {
+                    mProcessLoggingApkHashes.remove(apkPath);
+                }
+            });
+        }
+    }
+
+    private class ProcessLoggingRunnable implements Runnable {
+
+        private final ProcessRecord app;
+        private final Process.ProcessStartResult startResult;
+        private final long startTimestamp;
+
+        public ProcessLoggingRunnable(ProcessRecord app, Process.ProcessStartResult startResult,
+                long startTimestamp){
+            this.app = app;
+            this.startResult = startResult;
+            this.startTimestamp = startTimestamp;
+        }
+
+        @Override
+        public void run() {
+            String apkHash = computeStringHashOfApk(app);
+            SecurityLog.writeEvent(SecurityLog.TAG_APP_PROCESS_START,
+                    app.processName,
+                    startTimestamp,
+                    app.uid,
+                    startResult.pid,
+                    app.info.seinfo,
+                    apkHash);
+        }
+
+        private String computeStringHashOfApk(ProcessRecord app){
+            final String apkFile = app.info.sourceDir;
+            if(apkFile == null) {
+                return "No APK";
+            }
+            String apkHash = mProcessLoggingApkHashes.get(apkFile);
+            if (apkHash == null) {
+                try {
+                    byte[] hash = computeHashOfApkFile(apkFile);
+                    StringBuilder sb = new StringBuilder();
+                    for (int i = 0; i < hash.length; i++) {
+                        sb.append(String.format("%02x", hash[i]));
+                    }
+                    apkHash = sb.toString();
+                    mProcessLoggingApkHashes.put(apkFile, apkHash);
+                } catch (IOException | NoSuchAlgorithmException e) {
+                    Slog.w(TAG, "computeStringHashOfApk() failed", e);
+                }
+            }
+            return apkHash != null ? apkHash : "Failed to count APK hash";
+        }
+
+        private byte[] computeHashOfApkFile(String packageArchiveLocation)
+                throws IOException, NoSuchAlgorithmException {
+            MessageDigest md = MessageDigest.getInstance("SHA-256");
+            FileInputStream input = new FileInputStream(new File(packageArchiveLocation));
+            byte[] buffer = new byte[65536];
+            int size;
+            while((size = input.read(buffer)) > 0) {
+                md.update(buffer, 0, size);
+            }
+            input.close();
+            return md.digest();
+        }
+    }
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 71cfeab..cc86a62 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -245,8 +245,6 @@
     int mLayerRank = -1;
 
     Configuration mOverrideConfig = Configuration.EMPTY;
-    // STOPSHIP(b/26541093)
-    public String lastStackClear = "UNSET";
 
     TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
             IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 9331dd8..64c0891 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -689,6 +689,7 @@
         intentFilter.addAction(Intent.ACTION_USER_BACKGROUND);
         intentFilter.addAction(Intent.ACTION_USER_FOREGROUND);
         intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
+        intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
 
         intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
         // TODO merge orientation and rotation
@@ -3164,57 +3165,18 @@
             }
         }
         public void onServiceDisconnected(int profile) {
-            ArraySet<String> toRemove = null;
+
             switch (profile) {
             case BluetoothProfile.A2DP:
-                synchronized (mConnectedDevices) {
-                    synchronized (mA2dpAvrcpLock) {
-                        // Disconnect ALL DEVICE_OUT_BLUETOOTH_A2DP devices
-                        for (int i = 0; i < mConnectedDevices.size(); i++) {
-                            DeviceListSpec deviceSpec = mConnectedDevices.valueAt(i);
-                            if (deviceSpec.mDeviceType == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
-                                toRemove = toRemove != null ? toRemove : new ArraySet<String>();
-                                toRemove.add(deviceSpec.mDeviceAddress);
-                            }
-                        }
-                        if (toRemove != null) {
-                            int delay = checkSendBecomingNoisyIntent(
-                                                AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
-                                                0);
-                            for (int i = 0; i < toRemove.size(); i++) {
-                                makeA2dpDeviceUnavailableLater(toRemove.valueAt(i), delay);
-                            }
-                        }
-                    }
-                }
+                disconnectA2dp();
                 break;
 
             case BluetoothProfile.A2DP_SINK:
-                synchronized (mConnectedDevices) {
-                    // Disconnect ALL DEVICE_IN_BLUETOOTH_A2DP devices
-                    for(int i = 0; i < mConnectedDevices.size(); i++) {
-                        DeviceListSpec deviceSpec = mConnectedDevices.valueAt(i);
-                        if (deviceSpec.mDeviceType == AudioSystem.DEVICE_IN_BLUETOOTH_A2DP) {
-                            toRemove = toRemove != null ? toRemove : new ArraySet<String>();
-                            toRemove.add(deviceSpec.mDeviceAddress);
-                        }
-                    }
-                    if (toRemove != null) {
-                        for (int i = 0; i < toRemove.size(); i++) {
-                            makeA2dpSrcUnavailable(toRemove.valueAt(i));
-                        }
-                    }
-                }
+                disconnectA2dpSink();
                 break;
 
             case BluetoothProfile.HEADSET:
-                synchronized (mScoClients) {
-                    if (mBluetoothHeadsetDevice != null) {
-                        setBtScoDeviceConnectionState(mBluetoothHeadsetDevice,
-                                BluetoothProfile.STATE_DISCONNECTED);
-                    }
-                    mBluetoothHeadset = null;
-                }
+                disconnectHeadset();
                 break;
 
             default:
@@ -3223,6 +3185,65 @@
         }
     };
 
+    void disconnectAllBluetoothProfiles() {
+        disconnectA2dp();
+        disconnectA2dpSink();
+        disconnectHeadset();
+    }
+
+    void disconnectA2dp() {
+        synchronized (mConnectedDevices) {
+            synchronized (mA2dpAvrcpLock) {
+                ArraySet<String> toRemove = null;
+                // Disconnect ALL DEVICE_OUT_BLUETOOTH_A2DP devices
+                for (int i = 0; i < mConnectedDevices.size(); i++) {
+                    DeviceListSpec deviceSpec = mConnectedDevices.valueAt(i);
+                    if (deviceSpec.mDeviceType == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
+                        toRemove = toRemove != null ? toRemove : new ArraySet<String>();
+                        toRemove.add(deviceSpec.mDeviceAddress);
+                    }
+                }
+                if (toRemove != null) {
+                    int delay = checkSendBecomingNoisyIntent(
+                                        AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
+                                        0);
+                    for (int i = 0; i < toRemove.size(); i++) {
+                        makeA2dpDeviceUnavailableLater(toRemove.valueAt(i), delay);
+                    }
+                }
+            }
+        }
+    }
+
+    void disconnectA2dpSink() {
+        synchronized (mConnectedDevices) {
+            ArraySet<String> toRemove = null;
+            // Disconnect ALL DEVICE_IN_BLUETOOTH_A2DP devices
+            for(int i = 0; i < mConnectedDevices.size(); i++) {
+                DeviceListSpec deviceSpec = mConnectedDevices.valueAt(i);
+                if (deviceSpec.mDeviceType == AudioSystem.DEVICE_IN_BLUETOOTH_A2DP) {
+                    toRemove = toRemove != null ? toRemove : new ArraySet<String>();
+                    toRemove.add(deviceSpec.mDeviceAddress);
+                }
+            }
+            if (toRemove != null) {
+                for (int i = 0; i < toRemove.size(); i++) {
+                    makeA2dpSrcUnavailable(toRemove.valueAt(i));
+                }
+            }
+        }
+    }
+
+    void disconnectHeadset() {
+        synchronized (mScoClients) {
+            if (mBluetoothHeadsetDevice != null) {
+                setBtScoDeviceConnectionState(mBluetoothHeadsetDevice,
+                        BluetoothProfile.STATE_DISCONNECTED);
+            }
+            mBluetoothHeadset = null;
+        }
+    }
+
     private void onCheckMusicActive(String caller) {
         synchronized (mSafeMediaVolumeState) {
             if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE) {
@@ -5228,6 +5249,12 @@
                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
                 UserManagerService.getInstance().setUserRestriction(
                         UserManager.DISALLOW_RECORD_AUDIO, false, userId);
+            } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
+                state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
+                if (state == BluetoothAdapter.STATE_OFF ||
+                        state == BluetoothAdapter.STATE_TURNING_OFF) {
+                    disconnectAllBluetoothProfiles();
+                }
             }
         }
     } // end class AudioServiceBroadcastReceiver
@@ -6317,4 +6344,4 @@
             if (DEBUG_VOL) Log.d(TAG, "Reloaded controller service: " + this);
         }
     }
-}
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 75a74c0..f72b1c3 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -815,9 +815,13 @@
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
                 "no permission to read the sync stats");
 
+        final boolean canAccessAccounts =
+            mContext.checkCallingOrSelfPermission(Manifest.permission.GET_ACCOUNTS)
+                == PackageManager.PERMISSION_GRANTED;
         long identityToken = clearCallingIdentity();
         try {
-            return getSyncManager().getSyncStorageEngine().getCurrentSyncsCopy(userId);
+            return getSyncManager().getSyncStorageEngine()
+                .getCurrentSyncsCopy(userId, canAccessAccounts);
         } finally {
             restoreCallingIdentity(identityToken);
         }
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index f8b6f57..c13518b 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -1469,15 +1469,23 @@
     }
 
     /**
-     * @return a copy of the current syncs data structure. Will not return
-     * null.
+     * @param userId Id of user to return current sync info.
+     * @param canAccessAccounts Determines whether to redact Account information from the result.
+     * @return a copy of the current syncs data structure. Will not return null.
      */
-    public List<SyncInfo> getCurrentSyncsCopy(int userId) {
+    public List<SyncInfo> getCurrentSyncsCopy(int userId, boolean canAccessAccounts) {
         synchronized (mAuthorities) {
             final List<SyncInfo> syncs = getCurrentSyncsLocked(userId);
             final List<SyncInfo> syncsCopy = new ArrayList<SyncInfo>();
             for (SyncInfo sync : syncs) {
-                syncsCopy.add(new SyncInfo(sync));
+                SyncInfo copy;
+                if (!canAccessAccounts) {
+                    copy = SyncInfo.createAccountRedacted(
+                        sync.authorityId, sync.authority, sync.startTime);
+                } else {
+                    copy = new SyncInfo(sync);
+                }
+                syncsCopy.add(copy);
             }
             return syncsCopy;
         }
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index c359c4d..dd634fa 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -289,7 +289,7 @@
         final PowerManager pm =
                 (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, runningJob.getTag());
-        mWakeLock.setWorkSource(new WorkSource(runningJob.getUid()));
+        mWakeLock.setWorkSource(new WorkSource(runningJob.getSourceUid()));
         mWakeLock.setReferenceCounted(false);
         mWakeLock.acquire();
         mCallbackHandler.obtainMessage(MSG_SERVICE_BOUND).sendToTarget();
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index a621e6a..e6e9e49 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -92,6 +92,8 @@
     /** Copy constructor. */
     public JobStatus(JobStatus jobStatus) {
         this(jobStatus.getJob(), jobStatus.getUid(), jobStatus.getNumFailures());
+        this.sourceUserId = jobStatus.sourceUserId;
+        this.sourcePackageName = jobStatus.sourcePackageName;
         this.earliestRunTimeElapsedMillis = jobStatus.getEarliestRunTime();
         this.latestRunTimeElapsedMillis = jobStatus.getLatestRunTimeElapsed();
     }
@@ -132,6 +134,8 @@
     public JobStatus(JobStatus rescheduling, long newEarliestRuntimeElapsedMillis,
                       long newLatestRuntimeElapsedMillis, int backoffAttempt) {
         this(rescheduling.job, rescheduling.getUid(), backoffAttempt);
+        this.sourceUserId = rescheduling.sourceUserId;
+        this.sourcePackageName = rescheduling.sourcePackageName;
 
         earliestRunTimeElapsedMillis = newEarliestRuntimeElapsedMillis;
         latestRunTimeElapsedMillis = newLatestRuntimeElapsedMillis;
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 33b09e3..854ce31 100644
--- a/services/core/java/com/android/server/job/controllers/TimeController.java
+++ b/services/core/java/com/android/server/job/controllers/TimeController.java
@@ -202,7 +202,7 @@
     /**
      * Set an alarm with the {@link android.app.AlarmManager} for the next time at which a job's
      * delay will expire.
-     * This alarm <b>will not</b> wake up the phone.
+     * This alarm <b>will</b> wake up the phone.
      */
     private void setDelayExpiredAlarm(long alarmTimeElapsedMillis) {
         alarmTimeElapsedMillis = maybeAdjustAlarmTime(alarmTimeElapsedMillis);
@@ -238,7 +238,7 @@
             if (DEBUG) {
                 Slog.d(TAG, "Setting " + tag + " for: " + alarmTimeElapsed);
             }
-            mAlarmService.set(AlarmManager.ELAPSED_REALTIME, alarmTimeElapsed,
+            mAlarmService.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmTimeElapsed,
                     tag, listener, null);
         }
     }
diff --git a/services/core/java/com/android/server/net/NetworkIdentitySet.java b/services/core/java/com/android/server/net/NetworkIdentitySet.java
index f230bb3..68dc715 100644
--- a/services/core/java/com/android/server/net/NetworkIdentitySet.java
+++ b/services/core/java/com/android/server/net/NetworkIdentitySet.java
@@ -61,7 +61,7 @@
                 roaming = false;
             }
 
-            add(new NetworkIdentity(type, subType, subscriberId, networkId, false));
+            add(new NetworkIdentity(type, subType, subscriberId, networkId, roaming));
         }
     }
 
@@ -77,6 +77,19 @@
         }
     }
 
+    /** @return whether any {@link NetworkIdentity} in this set is considered roaming. */
+    public boolean isAnyMemberRoaming() {
+        if (isEmpty()) {
+            return false;
+        }
+        for (NetworkIdentity ident : this) {
+            if (ident.getRoaming()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private static void writeOptionalString(DataOutputStream out, String value) throws IOException {
         if (value != null) {
             out.writeByte(1);
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 4764300..38ebc80 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -75,6 +75,7 @@
 import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
 import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_UPDATED;
 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
+import static org.xmlpull.v1.XmlPullParser.END_TAG;
 import static org.xmlpull.v1.XmlPullParser.START_TAG;
 
 import android.Manifest;
@@ -153,6 +154,7 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.content.PackageMonitor;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.IndentingPrintWriter;
@@ -213,6 +215,8 @@
     private static final String TAG_NETWORK_POLICY = "network-policy";
     private static final String TAG_UID_POLICY = "uid-policy";
     private static final String TAG_APP_POLICY = "app-policy";
+    private static final String TAG_WHITELIST = "whitelist";
+    private static final String TAG_RESTRICT_BACKGROUND = "restrict-background";
 
     private static final String ATTR_VERSION = "version";
     private static final String ATTR_RESTRICT_BACKGROUND = "restrictBackground";
@@ -304,6 +308,11 @@
 
     private final SparseBooleanArray mPowerSaveTempWhitelistAppIds = new SparseBooleanArray();
 
+    /**
+     * UIDs that have been white-listed to avoid restricted background.
+     */
+    private final SparseBooleanArray mRestrictBackgroundWhitelistUids = new SparseBooleanArray();
+
     /** Set of ifaces that are metered. */
     private ArraySet<String> mMeteredIfaces = new ArraySet<>();
     /** Set of over-limit templates that have been notified. */
@@ -324,6 +333,8 @@
 
     private final AppOpsManager mAppOps;
 
+    private final MyPackageMonitor mPackageMonitor;
+
     // TODO: keep whitelist of system-critical services that should never have
     // rules enforced, such as system, phone, and radio UIDs.
 
@@ -363,6 +374,8 @@
         mPolicyFile = new AtomicFile(new File(systemDir, "netpolicy.xml"));
 
         mAppOps = context.getSystemService(AppOpsManager.class);
+
+        mPackageMonitor = new MyPackageMonitor();
     }
 
     public void bindConnectivityManager(IConnectivityManager connManager) {
@@ -431,6 +444,8 @@
 
         mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
 
+        mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
+
         synchronized (mRulesLock) {
             updatePowerSaveWhitelistLocked();
             mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
@@ -1127,7 +1142,7 @@
         // If we are in restrict power mode, we want to treat all interfaces
         // as metered, to restrict access to the network by uid.  However, we
         // will not have a bandwidth limit.  Also only do this if restrict
-        // background data use is *not* enabled, since that takes precendence
+        // background data use is *not* enabled, since that takes precedence
         // use over those networks can have a cost associated with it).
         final boolean powerSave = mRestrictPower && !mRestrictBackground;
 
@@ -1339,6 +1354,7 @@
 
             int type;
             int version = VERSION_INIT;
+            boolean insideWhitelist = false;
             while ((type = in.next()) != END_DOCUMENT) {
                 final String tag = in.getName();
                 if (type == START_TAG) {
@@ -1431,7 +1447,17 @@
                         } else {
                             Slog.w(TAG, "unable to apply policy to UID " + uid + "; ignoring");
                         }
+                    } else if (TAG_WHITELIST.equals(tag)) {
+                        insideWhitelist = true;
+                    } else if (TAG_RESTRICT_BACKGROUND.equals(tag) && insideWhitelist) {
+                        final int uid = readIntAttribute(in, ATTR_UID);
+                        mRestrictBackgroundWhitelistUids.put(uid, true);
                     }
+                } else if (type == END_TAG) {
+                    if (TAG_WHITELIST.equals(tag)) {
+                        insideWhitelist = false;
+                    }
+
                 }
             }
 
@@ -1519,6 +1545,21 @@
             }
 
             out.endTag(null, TAG_POLICY_LIST);
+
+            // write all whitelists
+            out.startTag(null, TAG_WHITELIST);
+
+            // restrict background whitelist
+            final int size = mRestrictBackgroundWhitelistUids.size();
+            for (int i = 0; i < size; i++) {
+                final int uid = mRestrictBackgroundWhitelistUids.keyAt(i);
+                out.startTag(null, TAG_RESTRICT_BACKGROUND);
+                writeIntAttribute(out, ATTR_UID, uid);
+                out.endTag(null, TAG_RESTRICT_BACKGROUND);
+            }
+
+            out.endTag(null, TAG_WHITELIST);
+
             out.endDocument();
 
             mPolicyFile.finishWrite(fos);
@@ -1789,6 +1830,49 @@
     }
 
     @Override
+    public void addRestrictBackgroundWhitelistedUid(int uid) {
+        mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
+        Slog.i(TAG, "adding uid " + uid + " to restrict background whitelist");
+        synchronized (mRulesLock) {
+            mRestrictBackgroundWhitelistUids.append(uid, true);
+            writePolicyLocked();
+            // TODO: call other update methods like updateNetworkRulesLocked?
+        }
+    }
+
+    @Override
+    public void removeRestrictBackgroundWhitelistedUid(int uid) {
+        mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
+        Slog.i(TAG, "removing uid " + uid + " from restrict background whitelist");
+        synchronized (mRulesLock) {
+            removeRestrictBackgroundWhitelistedUidLocked(uid);
+        }
+    }
+
+    private void removeRestrictBackgroundWhitelistedUidLocked(int uid) {
+        mRestrictBackgroundWhitelistUids.delete(uid);
+        writePolicyLocked();
+        // TODO: call other update methods like updateNetworkRulesLocked?
+    }
+
+    @Override
+    public int[] getRestrictBackgroundWhitelistedUids() {
+        mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
+        synchronized (mRulesLock) {
+            final int size = mRestrictBackgroundWhitelistUids.size();
+            final int[] whitelist = new int[size];
+            for (int i = 0; i < size; i++) {
+                whitelist[i] = mRestrictBackgroundWhitelistUids.keyAt(i);
+            }
+            if (LOGV) {
+                Slog.v(TAG, "getRestrictBackgroundWhitelistedUids(): "
+                        + mRestrictBackgroundWhitelistUids);
+            }
+            return whitelist;
+        }
+    }
+
+    @Override
     public boolean getRestrictBackground() {
         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
 
@@ -1978,6 +2062,18 @@
                 fout.decreaseIndent();
             }
 
+            size = mRestrictBackgroundWhitelistUids.size();
+            if (size > 0) {
+                fout.println("Restrict background whitelist uids:");
+                fout.increaseIndent();
+                for (int i = 0; i < size; i++) {
+                    fout.print("UID=");
+                    fout.print(mRestrictBackgroundWhitelistUids.keyAt(i));
+                    fout.println();
+                }
+                fout.decreaseIndent();
+            }
+
             final SparseBooleanArray knownUids = new SparseBooleanArray();
             collectKeys(mUidState, knownUids);
             collectKeys(mUidRules, knownUids);
@@ -2279,8 +2375,11 @@
             uidRules = RULE_REJECT_METERED;
         } else if (mRestrictBackground) {
             if (!uidForeground) {
-                // uid in background, and global background disabled
-                uidRules = RULE_REJECT_METERED;
+                // uid in background, global background disabled, and this uid is not on the white
+                // list of those allowed background access while global background is disabled
+                if (!mRestrictBackgroundWhitelistUids.get(uid)) {
+                    uidRules = RULE_REJECT_METERED;
+                }
             }
         } else if (mRestrictPower) {
             final boolean whitelisted = mPowerSaveWhitelistExceptIdleAppIds.get(appId)
@@ -2642,4 +2741,23 @@
             }
         }
     }
+
+    private class MyPackageMonitor extends PackageMonitor {
+
+        @Override
+        public void onPackageRemoved(String packageName, int uid) {
+            if (LOGV) Slog.v(TAG, "onPackageRemoved: " + packageName + " ->" + uid);
+            synchronized (mRulesLock) {
+                removeRestrictBackgroundWhitelistedUidLocked(uid);
+            }
+        }
+
+        @Override
+        public void onPackageRemovedAllUsers(String packageName, int uid) {
+            if (LOGV) Slog.v(TAG, "onPackageRemovedAllUsers: " + packageName + " ->" + uid);
+            synchronized (mRulesLock) {
+                removeRestrictBackgroundWhitelistedUidLocked(uid);
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/net/NetworkStatsCollection.java b/services/core/java/com/android/server/net/NetworkStatsCollection.java
index 102695e..eec7d93 100644
--- a/services/core/java/com/android/server/net/NetworkStatsCollection.java
+++ b/services/core/java/com/android/server/net/NetworkStatsCollection.java
@@ -17,6 +17,8 @@
 package com.android.server.net;
 
 import static android.net.NetworkStats.IFACE_ALL;
+import static android.net.NetworkStats.ROAMING_DEFAULT;
+import static android.net.NetworkStats.ROAMING_ROAMING;
 import static android.net.NetworkStats.SET_ALL;
 import static android.net.NetworkStats.SET_DEFAULT;
 import static android.net.NetworkStats.TAG_NONE;
@@ -218,6 +220,7 @@
                 entry.uid = key.uid;
                 entry.set = key.set;
                 entry.tag = key.tag;
+                entry.roaming = key.ident.isAnyMemberRoaming() ? ROAMING_ROAMING : ROAMING_DEFAULT;
                 entry.rxBytes = historyEntry.rxBytes;
                 entry.rxPackets = historyEntry.rxPackets;
                 entry.txBytes = historyEntry.txBytes;
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index 06f828e..89e89b0 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -93,7 +93,8 @@
                         // skip previously failing package
                         continue;
                     }
-                    if (!pm.performDexOpt(pkg, /* instruction set */ null, useJitProfiles)) {
+                    if (!pm.performDexOpt(pkg, /* instruction set */ null, useJitProfiles,
+                            /* extractOnly */ false)) {
                         // there was a problem running dexopt,
                         // remember this so we do not keep retrying.
                         sFailedPackageNames.add(pkg);
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 366edf9..cf876ee 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -47,8 +47,8 @@
     public static final int DEXOPT_DEBUGGABLE   = 1 << 3;
     /** The system boot has finished */
     public static final int DEXOPT_BOOTCOMPLETE = 1 << 4;
-    /** Run the application with the JIT compiler */
-    public static final int DEXOPT_USEJIT       = 1 << 5;
+    /** Do not compile, only extract bytecode into an OAT file */
+    public static final int DEXOPT_EXTRACTONLY  = 1 << 5;
 
     /** @hide */
     @IntDef(flag = true, value = {
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 18618d5..d82bb3d 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.ILauncherApps;
 import android.content.pm.IOnAppsChangedListener;
 import android.content.pm.IPackageManager;
@@ -246,6 +247,25 @@
         }
 
         @Override
+        public ApplicationInfo getApplicationInfo(String packageName, int flags, UserHandle user)
+                throws RemoteException {
+            ensureInUserProfiles(user, "Cannot check package for unrelated profile " + user);
+            if (!isUserEnabled(user)) {
+                return null;
+            }
+
+            long ident = Binder.clearCallingIdentity();
+            try {
+                IPackageManager pm = AppGlobals.getPackageManager();
+                ApplicationInfo info = pm.getApplicationInfo(packageName, flags,
+                        user.getIdentifier());
+                return info;
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override
         public boolean isActivityEnabled(ComponentName component, UserHandle user)
                 throws RemoteException {
             ensureInUserProfiles(user, "Cannot check component for unrelated profile " + user);
@@ -467,6 +487,44 @@
                 super.onPackagesUnavailable(packages);
             }
 
+            @Override
+            public void onPackagesSuspended(String[] packages) {
+                UserHandle user = new UserHandle(getChangingUserId());
+                final int n = mListeners.beginBroadcast();
+                for (int i = 0; i < n; i++) {
+                    IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
+                    UserHandle listeningUser = (UserHandle) mListeners.getBroadcastCookie(i);
+                    if (!isEnabledProfileOf(user, listeningUser, "onPackagesSuspended")) continue;
+                    try {
+                        listener.onPackagesSuspended(user, packages);
+                    } catch (RemoteException re) {
+                        Slog.d(TAG, "Callback failed ", re);
+                    }
+                }
+                mListeners.finishBroadcast();
+
+                super.onPackagesSuspended(packages);
+            }
+
+            @Override
+            public void onPackagesUnsuspended(String[] packages) {
+                UserHandle user = new UserHandle(getChangingUserId());
+                final int n = mListeners.beginBroadcast();
+                for (int i = 0; i < n; i++) {
+                    IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
+                    UserHandle listeningUser = (UserHandle) mListeners.getBroadcastCookie(i);
+                    if (!isEnabledProfileOf(user, listeningUser, "onPackagesUnsuspended")) continue;
+                    try {
+                        listener.onPackagesUnsuspended(user, packages);
+                    } catch (RemoteException re) {
+                        Slog.d(TAG, "Callback failed ", re);
+                    }
+                }
+                mListeners.finishBroadcast();
+
+                super.onPackagesUnsuspended(packages);
+            }
+
         }
 
         class PackageCallbackList<T extends IInterface> extends RemoteCallbackList<T> {
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 44b51d4..bce7223 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -41,7 +41,7 @@
 import static com.android.server.pm.Installer.DEXOPT_DEBUGGABLE;
 import static com.android.server.pm.Installer.DEXOPT_PUBLIC;
 import static com.android.server.pm.Installer.DEXOPT_SAFEMODE;
-import static com.android.server.pm.Installer.DEXOPT_USEJIT;
+import static com.android.server.pm.Installer.DEXOPT_EXTRACTONLY;
 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
 
@@ -82,7 +82,7 @@
      * {@link PackageManagerService#mInstallLock}.
      */
     int performDexOpt(PackageParser.Package pkg, String[] instructionSets,
-            boolean inclDependencies, String volumeUuid, boolean useProfiles) {
+            boolean inclDependencies, boolean useProfiles, boolean extractOnly) {
         ArraySet<String> done;
         if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
             done = new ArraySet<String>();
@@ -97,7 +97,8 @@
                 mDexoptWakeLock.acquire();
             }
             try {
-                return performDexOptLI(pkg, instructionSets, done, volumeUuid, useProfiles);
+                return performDexOptLI(pkg, instructionSets, done, useProfiles,
+                        extractOnly);
             } finally {
                 if (useLock) {
                     mDexoptWakeLock.release();
@@ -107,7 +108,7 @@
     }
 
     private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets,
-            ArraySet<String> done, String volumeUuid, boolean useProfiles) {
+            ArraySet<String> done, boolean useProfiles, boolean extractOnly) {
         final String[] instructionSets = targetInstructionSets != null ?
                 targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
 
@@ -173,29 +174,32 @@
                 Log.i(TAG, "Running dexopt (" + dexoptType + ") on: " + path + " pkg="
                         + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
                         + " vmSafeMode=" + vmSafeMode + " debuggable=" + debuggable
-                        + " oatDir = " + oatDir);
+                        + " extractOnly=" + extractOnly + " oatDir = " + oatDir);
                 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
                 final int dexFlags =
                         (!pkg.isForwardLocked() ? DEXOPT_PUBLIC : 0)
                         | (vmSafeMode ? DEXOPT_SAFEMODE : 0)
                         | (debuggable ? DEXOPT_DEBUGGABLE : 0)
+                        | (extractOnly ? DEXOPT_EXTRACTONLY : 0)
                         | DEXOPT_BOOTCOMPLETE;
                 try {
                     mPackageManagerService.mInstaller.dexopt(path, sharedGid,
                             pkg.packageName, dexCodeInstructionSet, dexoptNeeded, oatDir,
-                            dexFlags, volumeUuid, useProfiles);
+                            dexFlags, pkg.volumeUuid, useProfiles);
                     performedDexOpt = true;
                 } catch (InstallerException e) {
                     Slog.w(TAG, "Failed to dexopt", e);
                 }
             }
 
-            // At this point we haven't failed dexopt and we haven't deferred dexopt. We must
-            // either have either succeeded dexopt, or have had getDexOptNeeded tell us
-            // it isn't required. We therefore mark that this package doesn't need dexopt unless
-            // it's forced. performedDexOpt will tell us whether we performed dex-opt or skipped
-            // it.
-            pkg.mDexOptPerformed.add(dexCodeInstructionSet);
+            if (!extractOnly) {
+                // At this point we haven't failed dexopt and we haven't deferred dexopt. We must
+                // either have either succeeded dexopt, or have had getDexOptNeeded tell us
+                // it isn't required. We therefore mark that this package doesn't need dexopt unless
+                // it's forced. performedDexOpt will tell us whether we performed dex-opt or skipped
+                // it.
+                pkg.mDexOptPerformed.add(dexCodeInstructionSet);
+            }
         }
 
         // If we've gotten here, we're sure that no error occurred and that we haven't
@@ -248,8 +252,8 @@
             if (libPkg != null && !done.contains(libName)) {
                 // TODO: Analyze and investigate if we (should) profile libraries.
                 // Currently this will do a full compilation of the library.
-                performDexOptLI(libPkg, instructionSets, done,
-                        StorageManager.UUID_PRIVATE_INTERNAL, /*useProfiles*/ false);
+                performDexOptLI(libPkg, instructionSets, done, /*useProfiles*/ false,
+                        /* extractOnly */ false);
             }
         }
     }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 88198d4..f05e45f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -34,6 +34,7 @@
 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;
@@ -627,6 +628,9 @@
     // List of packages names to keep cached, even if they are uninstalled for all users
     private List<String> mKeepUninstalledPackages;
 
+    private boolean mUseJitProfiles =
+            SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
+
     private static class IFVerificationParams {
         PackageParser.Package pkg;
         boolean replacing;
@@ -3258,7 +3262,7 @@
     /**
      * Update given flags when being used to request {@link ResolveInfo}.
      */
-    private int updateFlagsForResolve(int flags, int userId, Object cookie) {
+    int updateFlagsForResolve(int flags, int userId, Object cookie) {
         return updateFlagsForComponent(flags, userId, cookie);
     }
 
@@ -6624,6 +6628,23 @@
         }
     }
 
+    @Override
+    public void extractPackagesIfNeeded() {
+        enforceSystemOrRoot("Only the system can request package extraction");
+
+        // Extract pacakges only if profile-guided compilation is enabled because
+        // otherwise BackgroundDexOptService will not dexopt them later.
+        if (mUseJitProfiles) {
+            ArraySet<String> pkgs = getOptimizablePackages();
+            if (pkgs != null) {
+                for (String pkg : pkgs) {
+                    performDexOpt(pkg, null /* instructionSet */, false /* useProfiles */,
+                            true /* extractOnly */);
+                }
+            }
+        }
+    }
+
     private ArraySet<String> getPackageNamesForIntent(Intent intent, int userId) {
         List<ResolveInfo> ris = null;
         try {
@@ -6654,25 +6675,27 @@
     // TODO: this is not used nor needed. Delete it.
     @Override
     public boolean performDexOptIfNeeded(String packageName, String instructionSet) {
-        return performDexOptTraced(packageName, instructionSet, false);
+        return performDexOptTraced(packageName, instructionSet, false /* useProfiles */,
+                false /* extractOnly */);
     }
 
-    public boolean performDexOpt(String packageName, String instructionSet, boolean useProfiles) {
-        return performDexOptTraced(packageName, instructionSet, useProfiles);
+    public boolean performDexOpt(String packageName, String instructionSet, boolean useProfiles,
+            boolean extractOnly) {
+        return performDexOptTraced(packageName, instructionSet, useProfiles, extractOnly);
     }
 
     private boolean performDexOptTraced(String packageName, String instructionSet,
-                boolean useProfiles) {
+                boolean useProfiles, boolean extractOnly) {
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
         try {
-            return performDexOptInternal(packageName, instructionSet, useProfiles);
+            return performDexOptInternal(packageName, instructionSet, useProfiles, extractOnly);
         } finally {
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
         }
     }
 
     private boolean performDexOptInternal(String packageName, String instructionSet,
-                boolean useProfiles) {
+                boolean useProfiles, boolean extractOnly) {
         PackageParser.Package p;
         final String targetInstructionSet;
         synchronized (mPackages) {
@@ -6694,7 +6717,7 @@
             synchronized (mInstallLock) {
                 final String[] instructionSets = new String[] { targetInstructionSet };
                 int result = mPackageDexOptimizer.performDexOpt(p, instructionSets,
-                        true /* inclDependencies */, p.volumeUuid, useProfiles);
+                        true /* inclDependencies */, useProfiles, extractOnly);
                 return result == PackageDexOptimizer.DEX_OPT_PERFORMED;
             }
         } finally {
@@ -6739,7 +6762,8 @@
             // Whoever is calling forceDexOpt wants a fully compiled package.
             // Don't use profiles since that may cause compilation to be skipped.
             final int res = mPackageDexOptimizer.performDexOpt(pkg, instructionSets,
-                    true /* inclDependencies */, pkg.volumeUuid, false /* useProfiles */);
+                    true /* inclDependencies */, false /* useProfiles */,
+                    false /* extractOnly */);
 
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
             if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
@@ -10079,6 +10103,19 @@
         info.sendBroadcast(false, false, false);
     }
 
+    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
+        if (pkgList.length > 0) {
+            Bundle extras = new Bundle(1);
+            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
+
+            sendPackageBroadcast(
+                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
+                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
+                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
+                    new int[] {userId});
+        }
+    }
+
     /**
      * Returns true if application is not found or there was an error. Otherwise it returns
      * the hidden state of the package for the given user.
@@ -10165,25 +10202,39 @@
         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, true,
                 "setPackageSuspended for user " + userId);
 
+        // TODO: investigate and add more restrictions for suspending crucial packages.
+        if (isPackageDeviceAdmin(packageName, userId)) {
+            Slog.w(TAG, "Not suspending/un-suspending package \"" + packageName
+                    + "\": has active device admin");
+            return false;
+        }
+
         long callingId = Binder.clearCallingIdentity();
         try {
+            boolean changed = false;
+            boolean success = false;
+            int appId = -1;
             synchronized (mPackages) {
                 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
                 if (pkgSetting != null) {
                     if (pkgSetting.getSuspended(userId) != suspended) {
                         pkgSetting.setSuspended(suspended, userId);
                         mSettings.writePackageRestrictionsLPr(userId);
+                        appId = pkgSetting.appId;
+                        changed = true;
                     }
-
-                    // TODO:
-                    // * broadcast a PACKAGE_(UN)SUSPENDED intent for launchers to pick up
-                    // * remove app from recents (kill app it if it is running)
-                    // * erase existing notifications for this app
-                    return true;
+                    success = true;
                 }
-
-                return false;
             }
+
+            if (changed) {
+                sendPackagesSuspendedForUser(new String[]{packageName}, userId, suspended);
+                if (suspended) {
+                    killApplication(packageName, UserHandle.getUid(userId, appId),
+                            "suspending package");
+                }
+            }
+            return success;
         } finally {
             Binder.restoreCallingIdentity(callingId);
         }
@@ -12964,6 +13015,24 @@
                 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
                 return;
             }
+
+            // Extract package to save the VM unzipping the APK in memory during
+            // launch. Only do this if profile-guided compilation is enabled because
+            // otherwise BackgroundDexOptService will not dexopt the package later.
+            if (mUseJitProfiles) {
+                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
+                // Do not run PackageDexOptimizer through the local performDexOpt
+                // method because `pkg` is not in `mPackages` yet.
+                int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instructionSets */,
+                        false /* inclDependencies */, false /* useProfiles */,
+                        true /* extractOnly */);
+                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+                if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
+                    String msg = "Extracking package failed for " + pkgName;
+                    res.setError(INSTALL_FAILED_DEXOPT, msg);
+                    return;
+                }
+            }
         }
 
         if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 91c8683..bbbe693 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -3045,6 +3045,7 @@
     private void applyDefaultPreferredActivityLPw(PackageManagerService service,
             Intent intent, int flags, ComponentName cn, String scheme, PatternMatcher ssp,
             IntentFilter.AuthorityEntry auth, PatternMatcher path, int userId) {
+        flags = service.updateFlagsForResolve(flags, userId, intent);
         List<ResolveInfo> ri = service.mActivities.queryIntent(intent,
                 intent.getType(), flags, 0);
         if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Queried " + intent
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 3248fe6..1e057aa 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -730,23 +730,15 @@
     @Override
     public void setUserIcon(int userId, Bitmap bitmap) {
         checkManageUsersPermission("update users");
-        long ident = Binder.clearCallingIdentity();
-        try {
-            synchronized (mPackagesLock) {
-                UserData userData = getUserDataNoChecks(userId);
-                if (userData == null || userData.info.partial) {
-                    Slog.w(LOG_TAG, "setUserIcon: unknown user #" + userId);
-                    return;
-                }
-                writeBitmapLP(userData.info, bitmap);
-                writeUserLP(userData);
-            }
-            sendUserInfoChangedBroadcast(userId);
-        } finally {
-            Binder.restoreCallingIdentity(ident);
+        if (hasUserRestriction(UserManager.DISALLOW_SET_USER_ICON, userId)) {
+            Log.w(LOG_TAG, "Cannot set user icon. DISALLOW_SET_USER_ICON is enabled.");
+            return;
         }
+        mLocalService.setUserIcon(userId, bitmap);
     }
 
+
+
     private void sendUserInfoChangedBroadcast(int userId) {
         Intent changedIntent = new Intent(Intent.ACTION_USER_INFO_CHANGED);
         changedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
@@ -2901,6 +2893,25 @@
                 mIsUserManaged.put(userId, isManaged);
             }
         }
+
+        @Override
+        public void setUserIcon(int userId, Bitmap bitmap) {
+            long ident = Binder.clearCallingIdentity();
+            try {
+                synchronized (mPackagesLock) {
+                    UserData userData = getUserDataNoChecks(userId);
+                    if (userData == null || userData.info.partial) {
+                        Slog.w(LOG_TAG, "setUserIcon: unknown user #" + userId);
+                        return;
+                    }
+                    writeBitmapLP(userData.info, bitmap);
+                    writeUserLP(userData);
+                }
+                sendUserInfoChangedBroadcast(userId);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
     }
 
     private class Shell extends ShellCommand {
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index f0ed790..87f505d 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -92,7 +92,8 @@
             UserManager.DISALLOW_RECORD_AUDIO,
             UserManager.DISALLOW_CAMERA,
             UserManager.DISALLOW_RUN_IN_BACKGROUND,
-            UserManager.DISALLOW_DATA_ROAMING
+            UserManager.DISALLOW_DATA_ROAMING,
+            UserManager.DISALLOW_SET_USER_ICON
     );
 
     /**
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 806c4ca..3b61817 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -18,15 +18,18 @@
 
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
+import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
+import static android.content.pm.PackageManager.FEATURE_TELEVISION;
+import static android.content.pm.PackageManager.FEATURE_WATCH;
 import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
 import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
 import static android.view.WindowManager.LayoutParams.*;
-import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
-import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN;
-import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_CLOSED;
+import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVERED;
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVER_ABSENT;
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_UNCOVERED;
-import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVERED;
+import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
+import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_CLOSED;
+import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN;
 
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
@@ -189,6 +192,9 @@
     static final int DOUBLE_TAP_HOME_NOTHING = 0;
     static final int DOUBLE_TAP_HOME_RECENT_SYSTEM_UI = 1;
 
+    static final int SHORT_PRESS_WINDOW_NOTHING = 0;
+    static final int SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE = 1;
+
     static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP = 0;
     static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME = 1;
 
@@ -409,6 +415,7 @@
     int mDoublePressOnPowerBehavior;
     int mTriplePressOnPowerBehavior;
     int mShortPressOnSleepBehavior;
+    int mShortPressWindowBehavior;
     boolean mAwake;
     boolean mScreenOnEarly;
     boolean mScreenOnFully;
@@ -1654,6 +1661,11 @@
                 mDoubleTapOnHomeBehavior > DOUBLE_TAP_HOME_RECENT_SYSTEM_UI) {
             mDoubleTapOnHomeBehavior = LONG_PRESS_HOME_NOTHING;
         }
+
+        mShortPressWindowBehavior = SHORT_PRESS_WINDOW_NOTHING;
+        if (mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) {
+            mShortPressWindowBehavior = SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE;
+        }
     }
 
     @Override
@@ -5329,6 +5341,16 @@
                     msg.setAsynchronous(true);
                     msg.sendToTarget();
                 }
+                break;
+            }
+            case KeyEvent.KEYCODE_WINDOW: {
+                if (mShortPressWindowBehavior == SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE) {
+                    if (!down) {
+                        handlePipKey(event);
+                    }
+                    result &= ~ACTION_PASS_TO_USER;
+                }
+                break;
             }
         }
 
@@ -6302,11 +6324,9 @@
             @Override public void run() {
                 if (mBootMsgDialog == null) {
                     int theme;
-                    if (mContext.getPackageManager().hasSystemFeature(
-                            PackageManager.FEATURE_WATCH)) {
+                    if (mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH)) {
                         theme = com.android.internal.R.style.Theme_Micro_Dialog_Alert;
-                    } else if (mContext.getPackageManager().hasSystemFeature(
-                            PackageManager.FEATURE_TELEVISION)) {
+                    } else if (mContext.getPackageManager().hasSystemFeature(FEATURE_TELEVISION)) {
                         theme = com.android.internal.R.style.Theme_Leanback_Dialog_Alert;
                     } else {
                         theme = 0;
diff --git a/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java b/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java
index b06fe58..80e4341 100644
--- a/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java
+++ b/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java
@@ -89,7 +89,7 @@
 
     @Override
     public void onPointerEvent(MotionEvent event) {
-        if (mGestureDetector != null) {
+        if (mGestureDetector != null && event.isTouchEvent()) {
             mGestureDetector.onTouchEvent(event);
         }
         switch (event.getActionMasked()) {
diff --git a/services/core/java/com/android/server/policy/WindowOrientationListener.java b/services/core/java/com/android/server/policy/WindowOrientationListener.java
index 9916223..a32c017 100644
--- a/services/core/java/com/android/server/policy/WindowOrientationListener.java
+++ b/services/core/java/com/android/server/policy/WindowOrientationListener.java
@@ -87,22 +87,10 @@
         mHandler = handler;
         mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
         mRate = rate;
+        mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_DEVICE_ORIENTATION);
 
-        mSensorType = context.getResources().getString(
-                com.android.internal.R.string.config_orientationSensorType);
-        if (!TextUtils.isEmpty(mSensorType)) {
-            List<Sensor> sensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);
-            final int N = sensors.size();
-            for (int i = 0; i < N; i++) {
-                Sensor sensor = sensors.get(i);
-                if (mSensorType.equals(sensor.getStringType())) {
-                    mSensor = sensor;
-                    break;
-                }
-            }
-            if (mSensor != null) {
-                mOrientationJudge = new OrientationSensorJudge();
-            }
+        if (mSensor != null) {
+            mOrientationJudge = new OrientationSensorJudge();
         }
 
         if (mOrientationJudge == null) {
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 785f166..2732821 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -302,6 +302,13 @@
         }
     }
 
+    void markSurfacesExiting() {
+        for (int i = allAppWindows.size() - 1; i >= 0; i--) {
+            WindowState win = allAppWindows.get(i);
+            win.mExiting = true;
+        }
+    }
+
     /**
      * Checks whether we should save surfaces for this app.
      *
@@ -329,15 +336,14 @@
         if (!hasSavedSurface()) {
             return;
         }
-
-        if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG_WM,
-                "Restoring saved surfaces: " + this + ", allDrawn=" + allDrawn);
-
         mAnimatingWithSavedSurface = true;
         for (int i = windows.size() - 1; i >= 0; i--) {
             WindowState ws = windows.get(i);
             ws.restoreSavedSurface();
         }
+        // Mark the app allDrawn since it must be allDrawn at the time
+        // it was first saved.
+        allDrawn = true;
     }
 
     void destroySavedSurfaces() {
diff --git a/services/core/java/com/android/server/wm/DimLayer.java b/services/core/java/com/android/server/wm/DimLayer.java
index 6657a7b..fc5d8ce 100644
--- a/services/core/java/com/android/server/wm/DimLayer.java
+++ b/services/core/java/com/android/server/wm/DimLayer.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DIM_LAYER;
 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;
@@ -33,41 +34,42 @@
 
 public class 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;
-
-    public static final int RESIZING_HINT_DURATION_MS = 0;
+    private final WindowManagerService mService;
 
     /** Actual surface that dims */
-    SurfaceControl mDimSurface;
+    private SurfaceControl mDimSurface;
 
     /** Last value passed to mDimSurface.setAlpha() */
-    float mAlpha = 0;
+    private float mAlpha = 0;
 
     /** Last value passed to mDimSurface.setLayer() */
-    int mLayer = -1;
+    private int mLayer = -1;
 
     /** Next values to pass to mDimSurface.setPosition() and mDimSurface.setSize() */
-    Rect mBounds = new Rect();
+    private final Rect mBounds = new Rect();
 
     /** Last values passed to mDimSurface.setPosition() and mDimSurface.setSize() */
-    Rect mLastBounds = new Rect();
+    private final Rect mLastBounds = new Rect();
 
     /** True after mDimSurface.show() has been called, false after mDimSurface.hide(). */
     private boolean mShowing = false;
 
     /** Value of mAlpha when beginning transition to mTargetAlpha */
-    float mStartAlpha = 0;
+    private float mStartAlpha = 0;
 
     /** Final value of mAlpha following transition */
-    float mTargetAlpha = 0;
+    private float mTargetAlpha = 0;
 
     /** Time in units of SystemClock.uptimeMillis() at which the current transition started */
-    long mStartTime;
+    private long mStartTime;
 
     /** Time in milliseconds to take to transition from mStartAlpha to mTargetAlpha */
-    long mDuration;
+    private long mDuration;
+
+    private boolean mDestroyed = false;
+
+    private final int mDisplayId;
+
 
     /** Interface implemented by users of the dim layer */
     interface DimLayerUser {
@@ -80,11 +82,16 @@
         String toShortString();
     }
     /** The user of this dim layer. */
-    final DimLayerUser mUser;
+    private final DimLayerUser mUser;
 
     DimLayer(WindowManagerService service, DimLayerUser user, int displayId) {
         mUser = user;
-        if (DEBUG) Slog.v(TAG, "Ctor: displayId=" + displayId);
+        mDisplayId = displayId;
+        mService = service;
+        if (DEBUG_DIM_LAYER) Slog.v(TAG, "Ctor: displayId=" + displayId);
+    }
+
+    private void constructSurface(WindowManagerService service) {
         SurfaceControl.openTransaction();
         try {
             if (DEBUG_SURFACE_TRACE) {
@@ -99,7 +106,10 @@
             }
             if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG,
                     "  DIM " + mDimSurface + ": CREATE");
-            mDimSurface.setLayerStack(displayId);
+            mDimSurface.setLayerStack(mDisplayId);
+            adjustBounds();
+            adjustAlpha(mAlpha);
+            adjustLayer(mLayer);
         } catch (Exception e) {
             Slog.e(TAG_WM, "Exception creating Dim surface", e);
         } finally {
@@ -122,8 +132,15 @@
     }
 
     void setLayer(int layer) {
-        if (mLayer != layer) {
-            mLayer = layer;
+        if (mLayer == layer) {
+            return;
+        }
+        mLayer = layer;
+        adjustLayer(layer);
+    }
+
+    private void adjustLayer(int layer) {
+        if (mDimSurface != null) {
             mDimSurface.setLayer(layer);
         }
     }
@@ -133,23 +150,34 @@
     }
 
     private void setAlpha(float alpha) {
-        if (mAlpha != alpha) {
-            if (DEBUG) Slog.v(TAG, "setAlpha alpha=" + alpha);
-            try {
+        if (mAlpha == alpha) {
+            return;
+        }
+        mAlpha = alpha;
+        adjustAlpha(alpha);
+    }
+
+    private void adjustAlpha(float alpha) {
+        if (DEBUG_DIM_LAYER) Slog.v(TAG, "setAlpha alpha=" + alpha);
+        try {
+            if (mDimSurface != null) {
                 mDimSurface.setAlpha(alpha);
-                if (alpha == 0 && mShowing) {
-                    if (DEBUG) Slog.v(TAG, "setAlpha hiding");
+            }
+            if (alpha == 0 && mShowing) {
+                if (DEBUG_DIM_LAYER) Slog.v(TAG, "setAlpha hiding");
+                if (mDimSurface != null) {
                     mDimSurface.hide();
                     mShowing = false;
-                } else if (alpha > 0 && !mShowing) {
-                    if (DEBUG) Slog.v(TAG, "setAlpha showing");
+                }
+            } else if (alpha > 0 && !mShowing) {
+                if (DEBUG_DIM_LAYER) Slog.v(TAG, "setAlpha showing");
+                if (mDimSurface != null) {
                     mDimSurface.show();
                     mShowing = true;
                 }
-            } catch (RuntimeException e) {
-                Slog.w(TAG, "Failure setting alpha immediately", e);
             }
-            mAlpha = alpha;
+        } catch (RuntimeException e) {
+            Slog.w(TAG, "Failure setting alpha immediately", e);
         }
     }
 
@@ -176,8 +204,10 @@
             yPos = -1 * dh / 6;
         }
 
-        mDimSurface.setPosition(xPos, yPos);
-        mDimSurface.setSize(dw, dh);
+        if (mDimSurface != null) {
+            mDimSurface.setPosition(xPos, yPos);
+            mDimSurface.setSize(dw, dh);
+        }
 
         mLastBounds.set(mBounds);
     }
@@ -209,7 +239,7 @@
      * NOTE: Must be called with Surface transaction open. */
     void show() {
         if (isAnimating()) {
-            if (DEBUG) Slog.v(TAG, "show: immediate");
+            if (DEBUG_DIM_LAYER) Slog.v(TAG, "show: immediate");
             show(mLayer, mTargetAlpha, 0);
         }
     }
@@ -223,15 +253,19 @@
      * @param duration How long to take to get there in milliseconds.
      */
     void show(int layer, float alpha, long duration) {
-        if (DEBUG) Slog.v(TAG, "show: layer=" + layer + " alpha=" + alpha
-                + " duration=" + duration);
-        if (mDimSurface == null) {
+        if (DEBUG_DIM_LAYER) Slog.v(TAG, "show: layer=" + layer + " alpha=" + alpha
+                + " duration=" + duration + ", mDestroyed=" + mDestroyed);
+        if (mDestroyed) {
             Slog.e(TAG, "show: no Surface");
             // Make sure isAnimating() returns false.
             mTargetAlpha = mAlpha = 0;
             return;
         }
 
+        if (mDimSurface == null) {
+            constructSurface(mService);
+        }
+
         if (!mLastBounds.equals(mBounds)) {
             adjustBounds();
         }
@@ -252,15 +286,15 @@
             }
         }
         mTargetAlpha = alpha;
-        if (DEBUG) Slog.v(TAG, "show: mStartAlpha=" + mStartAlpha + " mStartTime=" + mStartTime
-                + " mTargetAlpha=" + mTargetAlpha);
+        if (DEBUG_DIM_LAYER) Slog.v(TAG, "show: mStartAlpha=" + mStartAlpha + " mStartTime="
+                + mStartTime + " mTargetAlpha=" + mTargetAlpha);
     }
 
     /** Immediate hide.
      * NOTE: Must be called with Surface transaction open. */
     void hide() {
         if (mShowing) {
-            if (DEBUG) Slog.v(TAG, "hide: immediate");
+            if (DEBUG_DIM_LAYER) Slog.v(TAG, "hide: immediate");
             hide(0);
         }
     }
@@ -273,7 +307,7 @@
      */
     void hide(long duration) {
         if (mShowing && (mTargetAlpha != 0 || durationEndsEarlier(duration))) {
-            if (DEBUG) Slog.v(TAG, "hide: duration=" + duration);
+            if (DEBUG_DIM_LAYER) Slog.v(TAG, "hide: duration=" + duration);
             show(mLayer, 0, duration);
         }
     }
@@ -285,13 +319,12 @@
      * @return True if animation is still required after this step.
      */
     boolean stepAnimation() {
-        if (mDimSurface == null) {
-            Slog.e(TAG, "stepAnimation: null Surface");
+        if (mDestroyed) {
+            Slog.e(TAG, "stepAnimation: surface destroyed");
             // Ensure that isAnimating() returns false;
             mTargetAlpha = mAlpha = 0;
             return false;
         }
-
         if (isAnimating()) {
             final long curTime = SystemClock.uptimeMillis();
             final float alphaDelta = mTargetAlpha - mStartAlpha;
@@ -301,7 +334,7 @@
                 // Don't exceed limits.
                 alpha = mTargetAlpha;
             }
-            if (DEBUG) Slog.v(TAG, "stepAnimation: curTime=" + curTime + " alpha=" + alpha);
+            if (DEBUG_DIM_LAYER) Slog.v(TAG, "stepAnimation: curTime=" + curTime + " alpha=" + alpha);
             setAlpha(alpha);
         }
 
@@ -310,11 +343,12 @@
 
     /** Cleanup */
     void destroySurface() {
-        if (DEBUG) Slog.v(TAG, "destroySurface.");
+        if (DEBUG_DIM_LAYER) Slog.v(TAG, "destroySurface.");
         if (mDimSurface != null) {
             mDimSurface.destroy();
             mDimSurface = null;
         }
+        mDestroyed = true;
     }
 
     public void printTo(String prefix, PrintWriter pw) {
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 7b0a8d7..18798e5 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -360,8 +360,6 @@
         mCurrentX = x;
         mCurrentY = y;
 
-        final int myPid = Process.myPid();
-
         // Move the surface to the given touch
         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(
                 TAG_WM, ">>> OPEN TRANSACTION notifyMoveLw");
@@ -376,7 +374,10 @@
             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(
                     TAG_WM, "<<< CLOSE TRANSACTION notifyMoveLw");
         }
+        notifyLocationLw(x, y);
+    }
 
+    void notifyLocationLw(float x, float y) {
         // Tell the affected window
         WindowState touchedWin = getTouchedWinAtPointLw(x, y);
         if (touchedWin == null) {
@@ -392,6 +393,8 @@
             }
         }
         try {
+            final int myPid = Process.myPid();
+
             // have we dragged over a new window?
             if ((touchedWin != mTargetWindow) && (mTargetWindow != null)) {
                 if (DEBUG_DRAG) {
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 8aaf430..d8cbbab 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -357,6 +357,8 @@
                 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(
                         TAG_WM, "<<< CLOSE TRANSACTION performDrag");
             }
+
+            mService.mDragState.notifyLocationLw(touchX, touchY);
         }
 
         return true;    // success!
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index 725bbbc..f7035c5 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -23,8 +23,6 @@
 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.WindowManagerDebugConfig.DEBUG_ORIENTATION;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
@@ -85,6 +83,10 @@
     private static final int CTRL_TOP    = 0x4;
     private static final int CTRL_BOTTOM = 0x8;
 
+    public static final float RESIZING_HINT_ALPHA = 0.5f;
+
+    public static final int RESIZING_HINT_DURATION_MS = 0;
+
     private final WindowManagerService mService;
     private WindowPositionerEventReceiver mInputEventReceiver;
     private Display mDisplay;
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 62d4f36..722c3b4 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -281,8 +281,7 @@
             final int flags = win.mAttrs.flags;
             boolean canBeForceHidden = mPolicy.canBeForceHidden(win, win.mAttrs);
             boolean shouldBeForceHidden = shouldForceHide(win);
-            if (winAnimator.mSurfaceController != null
-                    && winAnimator.mSurfaceController.hasSurface()) {
+            if (winAnimator.hasSurface()) {
                 final boolean wasAnimating = winAnimator.mWasAnimating;
                 final boolean nowAnimating = winAnimator.stepAnimationLocked(mCurrentTime);
                 winAnimator.mWasAnimating = nowAnimating;
diff --git a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
index 48d3e80..0979cd3 100644
--- a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
+++ b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
@@ -35,8 +35,8 @@
 
     static final boolean DEBUG_RESIZE = false;
     static final boolean DEBUG = false;
-    static final boolean DEBUG_ADD_REMOVE = true;
-    static final boolean DEBUG_FOCUS = true;
+    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;
@@ -50,15 +50,15 @@
     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 = true;
-    static final boolean DEBUG_STARTING_WINDOW = true;
+    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_LAYOUT_REPEATS = false;
     static final boolean DEBUG_SURFACE_TRACE = false;
     static final boolean DEBUG_WINDOW_TRACE = false;
     static final boolean DEBUG_TASK_MOVEMENT = false;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 4b0015e..d2e2639 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2679,20 +2679,11 @@
             } else {
                 winAnimator.mEnterAnimationPending = false;
                 winAnimator.mEnteringAnimation = false;
-                if (winAnimator.mSurfaceController != null &&
-                        winAnimator.mSurfaceController.hasSurface()) {
+                if (winAnimator.hasSurface() && !win.mExiting) {
                     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
-                    // the app sets visibility to invisible for the first time after resume,
-                    // or when the user exits immediately after a resume. In both cases, we
-                    // don't want to destroy the saved surface.
                     // If we are not currently running the exit animation, we
                     // need to see about starting one.
-                    final boolean notExitingOrAnimating =
-                            !win.mExiting && !win.isAnimatingWithSavedSurface();
-                    result |= notExitingOrAnimating ? RELAYOUT_RES_SURFACE_CHANGED : 0;
                     // We don't want to animate visibility of windows which are pending
                     // replacement. In the case of activity relaunch child windows
                     // could request visibility changes as they are detached from the main
@@ -2700,11 +2691,11 @@
                     // these visibility changes though, we would cause a visual glitch
                     // hiding the window before it's replacement was available.
                     // So we just do nothing on our side.
-                    if (notExitingOrAnimating && win.mWillReplaceWindow == false) {
-                        focusMayChange = tryStartingAnimation(win, winAnimator, isDefaultDisplay,
-                                focusMayChange);
-
+                    if (!win.mWillReplaceWindow) {
+                        focusMayChange = tryStartExitingAnimation(
+                                win, winAnimator, isDefaultDisplay, focusMayChange);
                     }
+                    result |= RELAYOUT_RES_SURFACE_CHANGED;
                 }
 
                 outSurface.release();
@@ -2787,7 +2778,7 @@
         return result;
     }
 
-    private boolean tryStartingAnimation(WindowState win, WindowStateAnimator winAnimator,
+    private boolean tryStartExitingAnimation(WindowState win, WindowStateAnimator winAnimator,
             boolean isDefaultDisplay, boolean focusMayChange) {
         // Try starting an animation; if there isn't one, we
         // can destroy the surface right away.
@@ -4240,6 +4231,7 @@
                         }
                     }
                 } else {
+                    wtoken.markSurfacesExiting();
                     mClosingApps.add(wtoken);
                     wtoken.mEnteringAnimation = false;
                 }
@@ -10278,10 +10270,6 @@
         return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, displayMetrics);
     }
 
-    void scheduleSurfaceDestroy(WindowState win) {
-        mDestroySurface.add(win);
-    }
-
     @Override
     public void registerDockedStackListener(IDockedStackListener listener) {
         if (!checkCallingPermission(android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS,
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index e8a02b0..dca7735 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1768,45 +1768,69 @@
         return mAppToken != null && mAppToken.mAnimatingWithSavedSurface;
     }
 
-    // Returns true if the surface is saved.
-    boolean destroyOrSaveSurface() {
-        Task task = getTask();
+    private boolean shouldSaveSurface() {
         if (ActivityManager.isLowRamDeviceStatic()) {
             // Don't save surfaces on Svelte devices.
-            mSurfaceSaved = false;
-        } else if (task == null || task.inHomeStack()
-                || task.getTopVisibleAppToken() != mAppToken) {
+            return false;
+        }
+
+        if (isChildWindow()) {
+            return false;
+        }
+
+        Task task = getTask();
+        if (task == null || task.inHomeStack()) {
             // 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.
-            mSurfaceSaved = false;
-        } else if (isChildWindow()) {
-            mSurfaceSaved = false;
-        } else {
-            mSurfaceSaved = mAppToken.shouldSaveSurface();
+            return false;
         }
-        if (mSurfaceSaved == false) {
+
+        final AppWindowToken taskTop = task.getTopVisibleAppToken();
+        if (taskTop != null && taskTop != mAppToken) {
+            // Don't save if the window is not the topmost window.
+            return false;
+        }
+
+        return mAppToken.shouldSaveSurface();
+    }
+
+    void destroyOrSaveSurface() {
+        mSurfaceSaved = shouldSaveSurface();
+        if (mSurfaceSaved) {
+            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
+                Slog.v(TAG, "Saving surface: " + this);
+            }
+
+            mWinAnimator.hide("saved surface");
+            mWinAnimator.mDrawState = WindowStateAnimator.NO_SURFACE;
+            setHasSurface(false);
+        } else {
             mWinAnimator.destroySurfaceLocked();
         }
-        return mSurfaceSaved;
     }
 
     public void destroySavedSurface() {
-        if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "Destroying saved surface: " + this);
         if (mSurfaceSaved) {
+            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
+                Slog.v(TAG, "Destroying saved surface: " + this);
+            }
             mWinAnimator.destroySurfaceLocked();
         }
     }
 
+    public void restoreSavedSurface() {
+        mSurfaceSaved = false;
+        setHasSurface(true);
+        mWinAnimator.mDrawState = WindowStateAnimator.READY_TO_SHOW;
+        if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
+            Slog.v(TAG, "Restoring saved surface: " + this);
+        }
+    }
+
     public boolean hasSavedSurface() {
         return mSurfaceSaved;
     }
 
-    public void restoreSavedSurface() {
-        mSurfaceSaved = false;
-        mWinAnimator.mDrawState = WindowStateAnimator.READY_TO_SHOW;
-    }
-
     @Override
     public boolean isDefaultDisplay() {
         final DisplayContent displayContent = getDisplayContent();
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index da4e191..cffcc5d 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -468,7 +468,7 @@
         if (WindowManagerService.localLOGV) Slog.v(
                 TAG, "Exit animation finished in " + this
                 + ": remove=" + mWin.mRemoveOnExit);
-        if (mSurfaceController != null && mSurfaceController.hasSurface()) {
+        if (hasSurface()) {
             mService.mDestroySurface.add(mWin);
             mWin.mDestroying = true;
             hide("finishExit");
@@ -734,6 +734,11 @@
         mTmpSize.bottom += scale * (attrs.surfaceInsets.top + attrs.surfaceInsets.bottom);
     }
 
+    boolean hasSurface() {
+        return !mWin.mSurfaceSaved
+                && mSurfaceController != null && mSurfaceController.hasSurface();
+    }
+
     void destroySurfaceLocked() {
         final AppWindowToken wtoken = mWin.mAppToken;
         if (wtoken != null) {
@@ -1229,7 +1234,7 @@
 
     void prepareSurfaceLocked(final boolean recoveringMemory) {
         final WindowState w = mWin;
-        if (mSurfaceController == null || !mSurfaceController.hasSurface()) {
+        if (!hasSurface()) {
             if (w.mOrientationChanging) {
                 if (DEBUG_ORIENTATION) {
                     Slog.v(TAG, "Orientation change skips hidden " + w);
@@ -1311,7 +1316,7 @@
                     w.mOrientationChanging = false;
                 }
             }
-            if (mSurfaceController != null && mSurfaceController.hasSurface()) {
+            if (hasSurface()) {
                 w.mToken.hasVisible = true;
             }
         } else {
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index f77e5a6..9012b98 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -1161,6 +1161,9 @@
                 appAnimator.animation = null;
             }
             wtoken.inPendingTransaction = false;
+
+            wtoken.restoreSavedSurfaces();
+
             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
@@ -1197,7 +1200,12 @@
                     // 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.mWillReplaceWindow) {
+                    //
+                    // We also don't clear the mExiting flag for windows which have the
+                    // mRemoveOnExit flag. This indicates an explicit remove request has been issued
+                    // by the client. We should let animation proceed and not clear this flag or
+                    // they won't eventually be removed by WindowStateAnimator#finishExit.
+                    if (!win.mWillReplaceWindow && !win.mRemoveOnExit) {
                         win.mExiting = false;
                     }
                     if (win.mWinAnimator.mAnimLayer > layer) {
@@ -1212,8 +1220,6 @@
             if (mService.mAppTransition.isNextAppTransitionThumbnailUp()) {
                 createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
             }
-
-            wtoken.restoreSavedSurfaces();
         }
         return topOpeningApp;
     }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 1ada0ac..eb75914 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -2237,6 +2237,7 @@
             case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
             case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
             case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
+            case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
                 return;
         }
         throw new IllegalArgumentException("Invalid quality constant: 0x"
@@ -3467,6 +3468,9 @@
                 }
             }
             quality = getPasswordQuality(null, userHandle, false);
+            if (quality == DevicePolicyManager.PASSWORD_QUALITY_MANAGED) {
+                quality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+            }
             if (quality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
                 int realQuality = LockPatternUtils.computePasswordQuality(password);
                 if (realQuality < quality
@@ -7028,7 +7032,7 @@
             int userId = UserHandle.getCallingUserId();
             long id = mInjector.binderClearCallingIdentity();
             try {
-                mUserManager.setUserIcon(userId, icon);
+                mUserManagerInternal.setUserIcon(userId, icon);
             } finally {
                 mInjector.binderRestoreCallingIdentity(id);
             }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 7ce945bf..8114031 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -31,8 +31,11 @@
 import android.os.Build;
 import android.os.Environment;
 import android.os.FactoryTest;
+import android.os.FileUtils;
 import android.os.IPowerManager;
 import android.os.Looper;
+import android.os.PowerManager;
+import android.os.RecoverySystem;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.StrictMode;
@@ -95,6 +98,8 @@
 
 import dalvik.system.VMRuntime;
 
+import java.io.File;
+import java.io.IOException;
 import java.util.Locale;
 import java.util.Timer;
 import java.util.TimerTask;
@@ -144,6 +149,9 @@
 
     private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst";
 
+    private static final String UNCRYPT_PACKAGE_FILE = "/cache/recovery/uncrypt_file";
+    private static final String BLOCK_MAP_FILE = "/cache/recovery/block.map";
+
     /**
      * Default theme used by the system context. This is used to style
      * system-provided dialogs, such as the Power Off dialog, and other
@@ -324,6 +332,30 @@
                 reason = null;
             }
 
+            // If it's a pending reboot into recovery to apply an update,
+            // always make sure uncrypt gets executed properly when needed.
+            // If '/cache/recovery/block.map' hasn't been created, stop the
+            // reboot which will fail for sure, and get a chance to capture a
+            // bugreport when that's still feasible. (Bug; 26444951)
+            if (PowerManager.REBOOT_RECOVERY.equals(reason)) {
+                File packageFile = new File(UNCRYPT_PACKAGE_FILE);
+                if (packageFile.exists()) {
+                    String filename = null;
+                    try {
+                        filename = FileUtils.readTextFile(packageFile, 0, null);
+                    } catch (IOException e) {
+                        Slog.e(TAG, "Error reading uncrypt package file", e);
+                    }
+
+                    if (filename != null && filename.startsWith("/data")) {
+                        if (!new File(BLOCK_MAP_FILE).exists()) {
+                            Slog.e(TAG, "Can't find block map file, uncrypt failed or " +
+                                       "unexpected runtime restart?");
+                            return;
+                        }
+                    }
+                }
+            }
             ShutdownThread.rebootOrShutdown(null, reboot, reason);
         }
     }
@@ -635,6 +667,14 @@
         }
         Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
 
+        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "ExtractPackagesIfNeeded");
+        try {
+            mPackageManagerService.extractPackagesIfNeeded();
+        } catch (Throwable e) {
+            reportWtf("extract packages", e);
+        }
+        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+
         try {
             ActivityManagerNative.getDefault().showBootMessage(
                     context.getResources().getText(
diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
index 204bc2e..8cbd32d 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
@@ -22,6 +22,9 @@
 import static android.net.ConnectivityManager.TYPE_WIFI;
 import static android.net.ConnectivityManager.TYPE_WIMAX;
 import static android.net.NetworkStats.IFACE_ALL;
+import static android.net.NetworkStats.ROAMING_ALL;
+import static android.net.NetworkStats.ROAMING_DEFAULT;
+import static android.net.NetworkStats.ROAMING_ROAMING;
 import static android.net.NetworkStats.SET_ALL;
 import static android.net.NetworkStats.SET_DEFAULT;
 import static android.net.NetworkStats.SET_FOREGROUND;
@@ -81,6 +84,8 @@
 import org.easymock.EasyMock;
 
 import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Tests for {@link NetworkStatsService}.
@@ -282,8 +287,9 @@
         // verify service recorded history
         assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
         assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10);
-        assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, 512L, 4L, 256L, 2L, 4);
-        assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, 512L, 4L, 256L, 2L, 6);
+        assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, ROAMING_DEFAULT, 512L, 4L, 256L, 2L, 4);
+        assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, ROAMING_DEFAULT, 512L, 4L, 256L, 2L,
+                6);
         assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
         verifyAndReset();
 
@@ -317,8 +323,9 @@
         // after systemReady(), we should have historical stats loaded again
         assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
         assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10);
-        assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, 512L, 4L, 256L, 2L, 4);
-        assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, 512L, 4L, 256L, 2L, 6);
+        assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, ROAMING_DEFAULT, 512L, 4L, 256L, 2L, 4);
+        assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, ROAMING_DEFAULT, 512L, 4L, 256L, 2L,
+                6);
         assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
         verifyAndReset();
 
@@ -670,16 +677,20 @@
         NetworkStats stats = mSession.getSummaryForAllUid(
                 sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
         assertEquals(3, stats.size());
-        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 1);
-        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 1);
-        assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, 2048L, 16L, 1024L, 8L, 0);
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 50L, 5L,
+                50L, 5L, 1);
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_DEFAULT, 10L, 1L, 10L,
+                1L, 1);
+        assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 2048L, 16L,
+                1024L, 8L, 0);
 
         // now verify that recent history only contains one uid
         final long currentTime = currentTimeMillis();
         stats = mSession.getSummaryForAllUid(
                 sTemplateWifi, currentTime - HOUR_IN_MILLIS, currentTime, true);
         assertEquals(1, stats.size());
-        assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0);
+        assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 1024L, 8L,
+                512L, 4L, 0);
 
         verifyAndReset();
     }
@@ -742,10 +753,61 @@
         final NetworkStats stats = mSession.getSummaryForAllUid(
                 sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
         assertEquals(4, stats.size());
-        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 1);
-        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 1);
-        assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 1);
-        assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 1);
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 128L, 2L,
+                128L, 2L, 1);
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_DEFAULT, 64L, 1L, 64L,
+                1L, 1);
+        assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, TAG_NONE, ROAMING_DEFAULT, 32L, 2L,
+                32L, 2L, 1);
+        assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, 0xFAAD, ROAMING_DEFAULT, 1L, 1L, 1L,
+                1L, 1);
+
+        verifyAndReset();
+    }
+
+    public void testRoaming() throws Exception {
+        // pretend that network comes online
+        expectCurrentTime();
+        expectDefaultSettings();
+        expectNetworkState(buildMobile3gState(IMSI_1, true /* isRoaming */));
+        expectNetworkStatsSummary(buildEmptyStats());
+        expectNetworkStatsUidDetail(buildEmptyStats());
+        expectNetworkStatsPoll();
+        expectBandwidthControlCheck();
+
+        replay();
+        mService.forceUpdateIfaces();
+        verifyAndReset();
+
+        // Create some traffic
+        incrementCurrentTime(HOUR_IN_MILLIS);
+        expectCurrentTime();
+        expectDefaultSettings();
+        expectNetworkStatsSummary(buildEmptyStats());
+        // Note that all traffic from NetworkManagementService is tagged as ROAMING_DEFAULT, because
+        // roaming isn't tracked at that layer. We layer it on top by inspecting the iface
+        // properties.
+        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, 128L, 2L,
+                        128L, 2L, 0L)
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_DEFAULT, 64L, 1L, 64L,
+                        1L, 0L));
+        expectNetworkStatsPoll();
+
+        replay();
+        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
+
+        // verify service recorded history
+        assertUidTotal(sTemplateImsi1, UID_RED, 128L, 2L, 128L, 2L, 0);
+
+        // verify entire history present
+        final NetworkStats stats = mSession.getSummaryForAllUid(
+                sTemplateImsi1, Long.MIN_VALUE, Long.MAX_VALUE, true);
+        assertEquals(2, stats.size());
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_ROAMING, 128L, 2L,
+                128L, 2L, 0);
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_ROAMING, 64L, 1L, 64L,
+                1L, 0);
 
         verifyAndReset();
     }
@@ -805,17 +867,19 @@
 
         // verify summary API
         final NetworkStats stats = mSession.getSummaryForNetwork(template, start, end);
-        assertValues(stats, IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, rxPackets, txBytes,
-                txPackets, operations);
+        assertValues(stats, IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_DEFAULT, rxBytes,
+                rxPackets, txBytes, txPackets, operations);
     }
 
     private void assertUidTotal(NetworkTemplate template, int uid, long rxBytes, long rxPackets,
             long txBytes, long txPackets, int operations) throws Exception {
-        assertUidTotal(template, uid, SET_ALL, rxBytes, rxPackets, txBytes, txPackets, operations);
+        assertUidTotal(template, uid, SET_ALL, ROAMING_ALL, rxBytes, rxPackets, txBytes, txPackets,
+                operations);
     }
 
-    private void assertUidTotal(NetworkTemplate template, int uid, int set, long rxBytes,
-            long rxPackets, long txBytes, long txPackets, int operations) throws Exception {
+    private void assertUidTotal(NetworkTemplate template, int uid, int set, int roaming,
+            long rxBytes, long rxPackets, long txBytes, long txPackets, int operations)
+            throws Exception {
         // verify history API
         final NetworkStatsHistory history = mSession.getHistoryForUid(
                 template, uid, set, TAG_NONE, FIELD_ALL);
@@ -825,8 +889,8 @@
         // verify summary API
         final NetworkStats stats = mSession.getSummaryForAllUid(
                 template, Long.MIN_VALUE, Long.MAX_VALUE, false);
-        assertValues(stats, IFACE_ALL, uid, set, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets,
-                operations);
+        assertValues(stats, IFACE_ALL, uid, set, TAG_NONE, roaming, rxBytes, rxPackets, txBytes,
+                txPackets, operations);
     }
 
     private void expectSystemReady() throws Exception {
@@ -933,18 +997,31 @@
     }
 
     private static void assertValues(NetworkStats stats, String iface, int uid, int set,
-            int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, int operations) {
+            int tag, int roaming, long rxBytes, long rxPackets, long txBytes, long txPackets,
+            int operations) {
         final NetworkStats.Entry entry = new NetworkStats.Entry();
+        List<Integer> sets = new ArrayList<>();
         if (set == SET_DEFAULT || set == SET_ALL) {
-            final int i = stats.findIndex(iface, uid, SET_DEFAULT, tag);
-            if (i != -1) {
-                entry.add(stats.getValues(i, null));
-            }
+            sets.add(SET_DEFAULT);
         }
         if (set == SET_FOREGROUND || set == SET_ALL) {
-            final int i = stats.findIndex(iface, uid, SET_FOREGROUND, tag);
-            if (i != -1) {
-                entry.add(stats.getValues(i, null));
+            sets.add(SET_FOREGROUND);
+        }
+
+        List<Integer> roamings = new ArrayList<>();
+        if (roaming == ROAMING_DEFAULT || roaming == ROAMING_ALL) {
+            roamings.add(ROAMING_DEFAULT);
+        }
+        if (roaming == ROAMING_ROAMING || roaming == ROAMING_ALL) {
+            roamings.add(ROAMING_ROAMING);
+        }
+
+        for (int s : sets) {
+            for (int r : roamings) {
+                final int i = stats.findIndex(iface, uid, s, tag, r);
+                if (i != -1) {
+                    entry.add(stats.getValues(i, null));
+                }
             }
         }
 
@@ -974,9 +1051,14 @@
     }
 
     private static NetworkState buildMobile3gState(String subscriberId) {
+        return buildMobile3gState(subscriberId, false /* isRoaming */);
+    }
+
+    private static NetworkState buildMobile3gState(String subscriberId, boolean isRoaming) {
         final NetworkInfo info = new NetworkInfo(
                 TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UMTS, null, null);
         info.setDetailedState(DetailedState.CONNECTED, null, null);
+        info.setRoaming(isRoaming);
         final LinkProperties prop = new LinkProperties();
         prop.setInterfaceName(TEST_IFACE);
         return new NetworkState(info, prop, null, null, subscriberId, null);
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index d45b26f..3e30188 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -298,6 +298,16 @@
     public static final String METADATA_IN_CALL_SERVICE_UI = "android.telecom.IN_CALL_SERVICE_UI";
 
     /**
+     * A boolean meta-data value indicating whether an {@link InCallService} implements an
+     * in-call user interface to be used while the device is in car-mode (see
+     * {@link android.content.res.Configuration.UI_MODE_TYPE_CAR}).
+     *
+     * @hide
+     */
+    public static final String METADATA_IN_CALL_SERVICE_CAR_MODE_UI =
+            "android.telecom.IN_CALL_SERVICE_CAR_MODE_UI";
+
+    /**
      * The dual tone multi-frequency signaling character sent to indicate the dialing system should
      * pause for a predefined period.
      */
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 9eff591..320d274 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -357,6 +357,34 @@
     public static final String KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL =
             "always_show_emergency_alert_onoff_bool";
 
+    /**
+     * The data call APN retry configuration for default type APN.
+     * @hide
+     */
+    public static final String KEY_CARRIER_DATA_CALL_RETRY_CONFIG_DEFAULT_STRING =
+            "carrier_data_call_retry_config_default_string";
+
+    /**
+     * The data call APN retry configuration for other type APNs.
+     * @hide
+     */
+    public static final String KEY_CARRIER_DATA_CALL_RETRY_CONFIG_OTHERS_STRING =
+            "carrier_data_call_retry_config_others_string";
+
+    /**
+     * Delay between trying APN from the pool
+     * @hide
+     */
+    public static final String KEY_CARRIER_DATA_CALL_APN_DELAY_DEFAULT_LONG =
+            "carrier_data_call_apn_delay_default_long";
+
+    /**
+     * Faster delay between trying APN from the pool
+     * @hide
+     */
+    public static final String KEY_CARRIER_DATA_CALL_APN_DELAY_FASTER_LONG =
+            "carrier_data_call_apn_delay_faster_long";
+
     /* The following 3 fields are related to carrier visual voicemail. */
 
     /**
@@ -619,6 +647,13 @@
         sDefaults.putBoolean(KEY_ALLOW_ADDING_APNS_BOOL, true);
         sDefaults.putBoolean(KEY_BROADCAST_EMERGENCY_CALL_STATE_CHANGES_BOOL, false);
         sDefaults.putBoolean(KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL, false);
+        sDefaults.putString(KEY_CARRIER_DATA_CALL_RETRY_CONFIG_DEFAULT_STRING,
+                "default_randomization=2000,5000,10000,20000,40000,80000:5000,160000:5000,"
+                        + "320000:5000,640000:5000,1280000:5000,1800000:5000");
+        sDefaults.putString(KEY_CARRIER_DATA_CALL_RETRY_CONFIG_OTHERS_STRING,
+                "max_retries=3, 5000, 5000, 5000");
+        sDefaults.putLong(KEY_CARRIER_DATA_CALL_APN_DELAY_DEFAULT_LONG, 20000);
+        sDefaults.putLong(KEY_CARRIER_DATA_CALL_APN_DELAY_FASTER_LONG, 3000);
 
         sDefaults.putStringArray(KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY, null);
         sDefaults.putStringArray(KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY, null);
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 39f3213..9998937 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -24,7 +24,6 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.net.Uri;
-import android.os.Looper;
 import android.telephony.Rlog;
 import android.os.Handler;
 import android.os.Message;
@@ -348,31 +347,7 @@
      * for #onSubscriptionsChanged to be invoked.
      */
     public static class OnSubscriptionsChangedListener {
-        private final Handler mHandler;
-
-        public OnSubscriptionsChangedListener() {
-            mHandler = new OnSubscriptionsChangedListenerHandler();
-        }
-
-        /**
-         * Contructor that takes in looper as parameter in case a subclass/instantiation needs
-         * to use a specific looper (like in tests where mainLooper may need to be used).
-         * @param looper Looper to be used for mHandler
-         * @hide
-         */
-        protected OnSubscriptionsChangedListener(Looper looper) {
-            mHandler = new OnSubscriptionsChangedListenerHandler(looper);
-        }
-
-        private class OnSubscriptionsChangedListenerHandler extends Handler {
-            private OnSubscriptionsChangedListenerHandler() {
-                super();
-            }
-
-            private OnSubscriptionsChangedListenerHandler(Looper looper) {
-                super(looper);
-            }
-
+        private final Handler mHandler  = new Handler() {
             @Override
             public void handleMessage(Message msg) {
                 if (DBG) {
@@ -380,7 +355,7 @@
                 }
                 OnSubscriptionsChangedListener.this.onSubscriptionsChanged();
             }
-        }
+        };
 
         /**
          * Callback invoked when there is any change to any SubscriptionInfo. Typically
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index d3c1aec..7eaa6a6 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -3494,10 +3494,13 @@
     /**
      * Returns the response of SIM Authentication through RIL for the default subscription.
      * Returns null if the Authentication hasn't been successful
+     *
+     * <p>Requires that the calling app has carrier privileges.
+     * @see #hasCarrierPrivileges
+     *
      * @param appType ICC application type (@see com.android.internal.telephony.PhoneConstants#APPTYPE_xxx)
      * @param data authentication challenge data
      * @return the response of SIM Authentication, or null if not available
-     * @hide
      */
     public String getIccSimChallengeResponse(int appType, String data) {
         return getIccSimChallengeResponse(getDefaultSubscription(), appType, data);
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index a4e9486..fcb967f 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -44,7 +44,9 @@
         CONNECTED,
         DISCONNECTING,
         FAILED,
-        RETRYING
+        RETRYING        // After moving retry manager to ApnContext, we'll never enter this state!
+                        // Todo: Remove this state and other places that use this state and then
+                        // rename SCANNING to RETRYING.
     }
 
     public enum Activity {
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index d346731..3b01827 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -235,7 +235,7 @@
          setRegion(part2.string());
      } else if (part2.length() == 4 && isAlpha(part2)) {
          setScript(part2.string());
-     } else if (part2.length() >= 5 && part2.length() <= 8) {
+     } else if (part2.length() >= 4 && part2.length() <= 8) {
          setVariant(part2.string());
      } else {
          valid = false;
@@ -250,7 +250,7 @@
      if (((part3.length() == 2 && isAlpha(part3)) ||
          (part3.length() == 3 && isNumber(part3))) && script[0]) {
          setRegion(part3.string());
-     } else if (part3.length() >= 5 && part3.length() <= 8) {
+     } else if (part3.length() >= 4 && part3.length() <= 8) {
          setVariant(part3.string());
      } else {
          valid = false;
@@ -261,7 +261,7 @@
      }
 
      const String8& part4 = parts[3];
-     if (part4.length() >= 5 && part4.length() <= 8) {
+     if (part4.length() >= 4 && part4.length() <= 8) {
          setVariant(part4.string());
      } else {
          valid = false;
@@ -280,7 +280,7 @@
 
     String8 part = parts[currentIndex];
     if (part[0] == 'b' && part[1] == '+') {
-        // This is a "modified" BCP-47 language tag. Same semantics as BCP-47 tags,
+        // This is a "modified" BCP 47 language tag. Same semantics as BCP 47 tags,
         // except that the separator is "+" and not "-".
         Vector<String8> subtags = AaptUtil::splitAndLowerCase(part, '+');
         subtags.removeItemsAt(0);
@@ -296,8 +296,11 @@
                     setRegion(subtags[1]);
                     break;
                 case 4:
-                    setScript(subtags[1]);
-                    break;
+                    if (isAlpha(subtags[1])) {
+                        setScript(subtags[1]);
+                        break;
+                    }
+                    // This is not alphabetical, so we fall through to variant
                 case 5:
                 case 6:
                 case 7:
@@ -305,7 +308,7 @@
                     setVariant(subtags[1]);
                     break;
                 default:
-                    fprintf(stderr, "ERROR: Invalid BCP-47 tag in directory name %s\n",
+                    fprintf(stderr, "ERROR: Invalid BCP 47 tag in directory name %s\n",
                             part.string());
                     return -1;
             }
@@ -322,13 +325,13 @@
                 setRegion(subtags[1]);
                 hasRegion = true;
             } else {
-                fprintf(stderr, "ERROR: Invalid BCP-47 tag in directory name %s\n", part.string());
+                fprintf(stderr, "ERROR: Invalid BCP 47 tag in directory name %s\n", part.string());
                 return -1;
             }
 
             // The third tag can either be a region code (if the second tag was
             // a script), else a variant code.
-            if (subtags[2].size() > 4) {
+            if (subtags[2].size() >= 4) {
                 setVariant(subtags[2]);
             } else {
                 setRegion(subtags[2]);
@@ -339,7 +342,7 @@
             setRegion(subtags[2]);
             setVariant(subtags[3]);
         } else {
-            fprintf(stderr, "ERROR: Invalid BCP-47 tag in directory name: %s\n", part.string());
+            fprintf(stderr, "ERROR: Invalid BCP 47 tag in directory name: %s\n", part.string());
             return -1;
         }
 
@@ -370,7 +373,7 @@
 void AaptLocaleValue::initFromResTable(const ResTable_config& config) {
     config.unpackLanguage(language);
     config.unpackRegion(region);
-    if (config.localeScript[0]) {
+    if (config.localeScriptWasProvided) {
         memcpy(script, config.localeScript, sizeof(config.localeScript));
     }
 
@@ -385,6 +388,10 @@
 
     if (script[0]) {
         memcpy(out->localeScript, script, sizeof(out->localeScript));
+        out->localeScriptWasProvided = true;
+    } else {
+        out->computeScript();
+        out->localeScriptWasProvided = false;
     }
 
     if (variant[0]) {
diff --git a/tools/aapt2/Locale.cpp b/tools/aapt2/Locale.cpp
index 20a2d0c..0369156 100644
--- a/tools/aapt2/Locale.cpp
+++ b/tools/aapt2/Locale.cpp
@@ -96,7 +96,7 @@
          setRegion(part2.c_str());
      } else if (part2.length() == 4 && isAlpha(part2)) {
          setScript(part2.c_str());
-     } else if (part2.length() >= 5 && part2.length() <= 8) {
+     } else if (part2.length() >= 4 && part2.length() <= 8) {
          setVariant(part2.c_str());
      } else {
          valid = false;
@@ -111,7 +111,7 @@
      if (((part3.length() == 2 && isAlpha(part3)) ||
          (part3.length() == 3 && isNumber(part3))) && script[0]) {
          setRegion(part3.c_str());
-     } else if (part3.length() >= 5 && part3.length() <= 8) {
+     } else if (part3.length() >= 4 && part3.length() <= 8) {
          setVariant(part3.c_str());
      } else {
          valid = false;
@@ -122,7 +122,7 @@
      }
 
      const std::string& part4 = parts[3];
-     if (part4.length() >= 5 && part4.length() <= 8) {
+     if (part4.length() >= 4 && part4.length() <= 8) {
          setVariant(part4.c_str());
      } else {
          valid = false;
@@ -141,7 +141,7 @@
 
     std::string& part = *iter;
     if (part[0] == 'b' && part[1] == '+') {
-        // This is a "modified" BCP-47 language tag. Same semantics as BCP-47 tags,
+        // This is a "modified" BCP 47 language tag. Same semantics as BCP 47 tags,
         // except that the separator is "+" and not "-".
         std::vector<std::string> subtags = util::splitAndLowercase(part, '+');
         subtags.erase(subtags.begin());
@@ -157,8 +157,12 @@
                     setRegion(subtags[1].c_str());
                     break;
                 case 4:
-                    setScript(subtags[1].c_str());
-                    break;
+                    if ('0' <= subtags[1][0] && subtags[1][0] <= '9') {
+                        // This is a variant: fall through
+                    } else {
+                        setScript(subtags[1].c_str());
+                        break;
+                    }
                 case 5:
                 case 6:
                 case 7:
@@ -184,7 +188,7 @@
 
             // The third tag can either be a region code (if the second tag was
             // a script), else a variant code.
-            if (subtags[2].size() > 4) {
+            if (subtags[2].size() >= 4) {
                 setVariant(subtags[2].c_str());
             } else {
                 setRegion(subtags[2].c_str());
@@ -249,7 +253,7 @@
 void LocaleValue::initFromResTable(const ResTable_config& config) {
     config.unpackLanguage(language);
     config.unpackRegion(region);
-    if (config.localeScript[0]) {
+    if (config.localeScriptWasProvided) {
         memcpy(script, config.localeScript, sizeof(config.localeScript));
     }
 
@@ -264,6 +268,10 @@
 
     if (script[0]) {
         memcpy(out->localeScript, script, sizeof(out->localeScript));
+        out->localeScriptWasProvided = true;
+    } else {
+        out->computeScript();
+        out->localeScriptWasProvided = false;
     }
 
     if (variant[0]) {
diff --git a/tools/aapt2/io/ZipArchive.cpp b/tools/aapt2/io/ZipArchive.cpp
index bf0f4aa..329dac9 100644
--- a/tools/aapt2/io/ZipArchive.cpp
+++ b/tools/aapt2/io/ZipArchive.cpp
@@ -75,11 +75,19 @@
 
 std::unique_ptr<ZipFileCollection> ZipFileCollection::create(const StringPiece& path,
                                                              std::string* outError) {
+    constexpr static const int32_t kEmptyArchive = -6;
+
     std::unique_ptr<ZipFileCollection> collection = std::unique_ptr<ZipFileCollection>(
             new ZipFileCollection());
 
     int32_t result = OpenArchive(path.data(), &collection->mHandle);
     if (result != 0) {
+        // If a zip is empty, result will be an error code. This is fine and we should
+        // return an empty ZipFileCollection.
+        if (result == kEmptyArchive) {
+            return collection;
+        }
+
         if (outError) *outError = ErrorCodeString(result);
         return {};
     }
diff --git a/tools/aapt2/link/Link.cpp b/tools/aapt2/link/Link.cpp
index 51b9cec..364a55b 100644
--- a/tools/aapt2/link/Link.cpp
+++ b/tools/aapt2/link/Link.cpp
@@ -551,12 +551,13 @@
             if (resourceFile) {
                 return mergeCompiledFile(file, std::move(resourceFile), override);
             }
-        } else {
-            // Ignore non .flat files. This could be classes.dex or something else that happens
-            // to be in an archive.
+
+            return false;
         }
 
-        return false;
+        // Ignore non .flat files. This could be classes.dex or something else that happens
+        // to be in an archive.
+        return true;
     }
 
     int run(const std::vector<std::string>& inputFiles) {
diff --git a/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java b/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java
index 6c949d9..1465f50 100644
--- a/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java
@@ -19,6 +19,8 @@
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 
+import android.graphics.Matrix;
+
 /**
  * Delegate implementing the native methods of {@link RenderNode}
  * <p/>
@@ -36,6 +38,19 @@
 
 
     private float mLift;
+    private float mTranslationX;
+    private float mTranslationY;
+    private float mTranslationZ;
+    private float mRotation;
+    private float mScaleX = 1;
+    private float mScaleY = 1;
+    private float mPivotX;
+    private float mPivotY;
+    private boolean mPivotExplicitlySet;
+    private int mLeft;
+    private int mRight;
+    private int mTop;
+    private int mBottom;
     @SuppressWarnings("UnusedDeclaration")
     private String mName;
 
@@ -69,4 +84,245 @@
         }
         return 0f;
     }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetTranslationX(long renderNode, float translationX) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mTranslationX != translationX) {
+            delegate.mTranslationX = translationX;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float nGetTranslationX(long renderNode) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null) {
+            return delegate.mTranslationX;
+        }
+        return 0f;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetTranslationY(long renderNode, float translationY) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mTranslationY != translationY) {
+            delegate.mTranslationY = translationY;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float nGetTranslationY(long renderNode) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null) {
+            return delegate.mTranslationY;
+        }
+        return 0f;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetTranslationZ(long renderNode, float translationZ) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mTranslationZ != translationZ) {
+            delegate.mTranslationZ = translationZ;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float nGetTranslationZ(long renderNode) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null) {
+            return delegate.mTranslationZ;
+        }
+        return 0f;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetRotation(long renderNode, float rotation) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mRotation != rotation) {
+            delegate.mRotation = rotation;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float nGetRotation(long renderNode) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null) {
+            return delegate.mRotation;
+        }
+        return 0f;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void getMatrix(RenderNode renderNode, Matrix outMatrix) {
+        outMatrix.reset();
+        if (renderNode != null) {
+            float rotation = renderNode.getRotation();
+            float translationX = renderNode.getTranslationX();
+            float translationY = renderNode.getTranslationY();
+            float pivotX = renderNode.getPivotX();
+            float pivotY = renderNode.getPivotY();
+            float scaleX = renderNode.getScaleX();
+            float scaleY = renderNode.getScaleY();
+
+            outMatrix.setTranslate(translationX, translationY);
+            outMatrix.preRotate(rotation, pivotX, pivotY);
+            outMatrix.preScale(scaleX, scaleY, pivotX, pivotY);
+        }
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetLeft(long renderNode, int left) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mLeft != left) {
+            delegate.mLeft = left;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetTop(long renderNode, int top) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mTop != top) {
+            delegate.mTop = top;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetRight(long renderNode, int right) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mRight != right) {
+            delegate.mRight = right;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetBottom(long renderNode, int bottom) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mBottom != bottom) {
+            delegate.mBottom = bottom;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetLeftTopRightBottom(long renderNode, int left, int top, int right,
+            int bottom) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && (delegate.mLeft != left || delegate.mTop != top || delegate
+                .mRight != right || delegate.mBottom != bottom)) {
+            delegate.mLeft = left;
+            delegate.mTop = top;
+            delegate.mRight = right;
+            delegate.mBottom = bottom;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nIsPivotExplicitlySet(long renderNode) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        return delegate != null && delegate.mPivotExplicitlySet;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetPivotX(long renderNode, float pivotX) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null) {
+            delegate.mPivotX = pivotX;
+            delegate.mPivotExplicitlySet = true;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float nGetPivotX(long renderNode) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null) {
+            if (delegate.mPivotExplicitlySet) {
+                return delegate.mPivotX;
+            } else {
+                return (delegate.mRight - delegate.mLeft) / 2.0f;
+            }
+        }
+        return 0f;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetPivotY(long renderNode, float pivotY) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null) {
+            delegate.mPivotY = pivotY;
+            delegate.mPivotExplicitlySet = true;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float nGetPivotY(long renderNode) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null) {
+            if (delegate.mPivotExplicitlySet) {
+                return delegate.mPivotY;
+            } else {
+                return (delegate.mBottom - delegate.mTop) / 2.0f;
+            }
+        }
+        return 0f;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetScaleX(long renderNode, float scaleX) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mScaleX != scaleX) {
+            delegate.mScaleX = scaleX;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float nGetScaleX(long renderNode) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null) {
+            return delegate.mScaleX;
+        }
+        return 0f;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static boolean nSetScaleY(long renderNode, float scaleY) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null && delegate.mScaleY != scaleY) {
+            delegate.mScaleY = scaleY;
+            return true;
+        }
+        return false;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static float nGetScaleY(long renderNode) {
+        RenderNode_Delegate delegate = sManager.getDelegate(renderNode);
+        if (delegate != null) {
+            return delegate.mScaleY;
+        }
+        return 0f;
+    }
 }
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 6e6ad8f..87f6106 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -192,6 +192,29 @@
         "android.view.RenderNode#nDestroyRenderNode",
         "android.view.RenderNode#nSetElevation",
         "android.view.RenderNode#nGetElevation",
+        "android.view.RenderNode#nSetTranslationX",
+        "android.view.RenderNode#nGetTranslationX",
+        "android.view.RenderNode#nSetTranslationY",
+        "android.view.RenderNode#nGetTranslationY",
+        "android.view.RenderNode#nSetTranslationZ",
+        "android.view.RenderNode#nGetTranslationZ",
+        "android.view.RenderNode#nSetRotation",
+        "android.view.RenderNode#nGetRotation",
+        "android.view.RenderNode#getMatrix",
+        "android.view.RenderNode#nSetLeft",
+        "android.view.RenderNode#nSetTop",
+        "android.view.RenderNode#nSetRight",
+        "android.view.RenderNode#nSetBottom",
+        "android.view.RenderNode#nSetLeftTopRightBottom",
+        "android.view.RenderNode#nSetPivotX",
+        "android.view.RenderNode#nGetPivotX",
+        "android.view.RenderNode#nSetPivotY",
+        "android.view.RenderNode#nGetPivotY",
+        "android.view.RenderNode#nSetScaleX",
+        "android.view.RenderNode#nGetScaleX",
+        "android.view.RenderNode#nSetScaleY",
+        "android.view.RenderNode#nGetScaleY",
+        "android.view.RenderNode#nIsPivotExplicitlySet",
         "android.view.ViewGroup#drawChild",
         "android.widget.TimePickerClockDelegate#getAmOrPmKeyCode",
         "com.android.internal.view.menu.MenuBuilder#createNewMenuItem",
diff --git a/tools/localedata/extract_icu_data.py b/tools/localedata/extract_icu_data.py
new file mode 100755
index 0000000..b071093
--- /dev/null
+++ b/tools/localedata/extract_icu_data.py
@@ -0,0 +1,286 @@
+#!/usr/bin/env python
+#
+# Copyright 2016 The Android Open Source Project. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+#
+
+"""Generate a C++ data table containing locale data."""
+
+import collections
+import glob
+import os.path
+import sys
+
+
+def get_locale_parts(locale):
+    """Split a locale into three parts, for langauge, script, and region."""
+    parts = locale.split('_')
+    if len(parts) == 1:
+        return (parts[0], None, None)
+    elif len(parts) == 2:
+        if len(parts[1]) == 4:  # parts[1] is a script
+            return (parts[0], parts[1], None)
+        else:
+            return (parts[0], None, parts[1])
+    else:
+        assert len(parts) == 3
+        return tuple(parts)
+
+
+def read_likely_subtags(input_file_name):
+    """Read and parse ICU's likelySubtags.txt."""
+    with open(input_file_name) as input_file:
+        likely_script_dict = {
+            # Android's additions for pseudo-locales. These internal codes make
+            # sure that the pseudo-locales would not match other English or
+            # Arabic locales. (We can't use private-use ISO 15924 codes, since
+            # they may be used by apps for other purposes.)
+            "en_XA": "~~~A",
+            "ar_XB": "~~~B",
+        }
+        representative_locales = {
+            # Android's additions
+            "en_Latn_GB", # representative for en_Latn_001
+            "es_Latn_MX", # representative for es_Latn_419
+            "es_Latn_US", # representative for es_Latn_419 (not the best idea,
+                          # but Android has been shipping with it for quite a
+                          # while. Fortunately, MX < US, so if both exist, MX
+                          # would be chosen.)
+        }
+        for line in input_file:
+            line = unicode(line, 'UTF-8').strip(u' \n\uFEFF').encode('UTF-8')
+            if line.startswith('//'):
+                continue
+            if '{' in line and '}' in line:
+                from_locale = line[:line.index('{')]
+                to_locale = line[line.index('"')+1:line.rindex('"')]
+                from_lang, from_scr, from_region = get_locale_parts(from_locale)
+                _, to_scr, to_region = get_locale_parts(to_locale)
+                if from_lang == 'und':
+                    continue  # not very useful for our purposes
+                if from_region is None and to_region != '001':
+                    representative_locales.add(to_locale)
+                if from_scr is None:
+                    likely_script_dict[from_locale] = to_scr
+        return likely_script_dict, frozenset(representative_locales)
+
+
+# From packLanguageOrRegion() in ResourceTypes.cpp
+def pack_language_or_region(inp, base):
+    """Pack langauge or region in a two-byte tuple."""
+    if inp is None:
+        return (0, 0)
+    elif len(inp) == 2:
+        return ord(inp[0]), ord(inp[1])
+    else:
+        assert len(inp) == 3
+        base = ord(base)
+        first = ord(inp[0]) - base
+        second = ord(inp[1]) - base
+        third = ord(inp[2]) - base
+
+        return (0x80 | (third << 2) | (second >>3),
+                ((second << 5) | first) & 0xFF)
+
+
+# From packLanguage() in ResourceTypes.cpp
+def pack_language(language):
+    """Pack language in a two-byte tuple."""
+    return pack_language_or_region(language, 'a')
+
+
+# From packRegion() in ResourceTypes.cpp
+def pack_region(region):
+    """Pack region in a two-byte tuple."""
+    return pack_language_or_region(region, '0')
+
+
+def pack_to_uint32(locale):
+    """Pack language+region of locale into a 32-bit unsigned integer."""
+    lang, _, region = get_locale_parts(locale)
+    plang = pack_language(lang)
+    pregion = pack_region(region)
+    return (plang[0] << 24) | (plang[1] << 16) | (pregion[0] << 8) | pregion[1]
+
+
+def dump_script_codes(all_scripts):
+    """Dump the SCRIPT_CODES table."""
+    print 'const char SCRIPT_CODES[][4] = {'
+    for index, script in enumerate(all_scripts):
+        print "    /* %-2d */ {'%c', '%c', '%c', '%c'}," % (
+            index, script[0], script[1], script[2], script[3])
+    print '};'
+    print
+
+
+def dump_script_data(likely_script_dict, all_scripts):
+    """Dump the script data."""
+    print
+    print 'const std::unordered_map<uint32_t, uint8_t> LIKELY_SCRIPTS({'
+    for locale in sorted(likely_script_dict.keys()):
+        script = likely_script_dict[locale]
+        print '    {0x%08Xu, %2du}, // %s -> %s' % (
+            pack_to_uint32(locale),
+            all_scripts.index(script),
+            locale.replace('_', '-'),
+            script)
+    print '});'
+
+
+def pack_to_uint64(locale):
+    """Pack a full locale into a 64-bit unsigned integer."""
+    _, script, _ = get_locale_parts(locale)
+    return ((pack_to_uint32(locale) << 32) |
+            (ord(script[0]) << 24) |
+            (ord(script[1]) << 16) |
+            (ord(script[2]) << 8) |
+            ord(script[3]))
+
+
+def dump_representative_locales(representative_locales):
+    """Dump the set of representative locales."""
+    print
+    print 'std::unordered_set<uint64_t> REPRESENTATIVE_LOCALES({'
+    for locale in sorted(representative_locales):
+        print '    0x%08Xllu, // %s' % (
+            pack_to_uint64(locale),
+            locale)
+    print '});'
+
+
+def read_and_dump_likely_data(icu_data_dir):
+    """Read and dump the likely-script data."""
+    likely_subtags_txt = os.path.join(icu_data_dir, 'misc', 'likelySubtags.txt')
+    likely_script_dict, representative_locales = read_likely_subtags(
+        likely_subtags_txt)
+
+    all_scripts = list(set(likely_script_dict.values()))
+    assert len(all_scripts) <= 256
+    all_scripts.sort()
+
+    dump_script_codes(all_scripts)
+    dump_script_data(likely_script_dict, all_scripts)
+    dump_representative_locales(representative_locales)
+    return likely_script_dict
+
+
+def read_parent_data(icu_data_dir):
+    """Read locale parent data from ICU data files."""
+    all_icu_data_files = glob.glob(os.path.join(icu_data_dir, '*', '*.txt'))
+    parent_dict = {}
+    for data_file in all_icu_data_files:
+        locale = os.path.splitext(os.path.basename(data_file))[0]
+        with open(data_file) as input_file:
+            for line in input_file:
+                if '%%Parent' in line:
+                    parent = line[line.index('"')+1:line.rindex('"')]
+                    if locale in parent_dict:
+                        # Different files shouldn't have different parent info
+                        assert parent_dict[locale] == parent
+                    else:
+                        parent_dict[locale] = parent
+                elif locale.startswith('ar_') and 'default{"latn"}' in line:
+                    # Arabic parent overrides for ASCII digits. Since
+                    # Unicode extensions are not supported in ResourceTypes,
+                    # we will use ar-015 (Arabic, Northern Africa) instead
+                    # of the more correct ar-u-nu-latn.
+                    parent_dict[locale] = 'ar_015'
+    return parent_dict
+
+
+def get_likely_script(locale, likely_script_dict):
+    """Find the likely script for a locale, given the likely-script dictionary.
+    """
+    if locale.count('_') == 2:
+        # it already has a script
+        return locale.split('_')[1]
+    elif locale in likely_script_dict:
+        return likely_script_dict[locale]
+    else:
+        language = locale.split('_')[0]
+        return likely_script_dict[language]
+
+
+def dump_parent_data(script_organized_dict):
+    """Dump information for parents of locales."""
+    sorted_scripts = sorted(script_organized_dict.keys())
+    print
+    for script in sorted_scripts:
+        parent_dict = script_organized_dict[script]
+        print ('const std::unordered_map<uint32_t, uint32_t> %s_PARENTS({'
+            % script.upper())
+        for locale in sorted(parent_dict.keys()):
+            parent = parent_dict[locale]
+            print '    {0x%08Xu, 0x%08Xu}, // %s -> %s' % (
+                pack_to_uint32(locale),
+                pack_to_uint32(parent),
+                locale.replace('_', '-'),
+                parent.replace('_', '-'))
+        print '});'
+        print
+
+    print 'const struct {'
+    print '    const char script[4];'
+    print '    const std::unordered_map<uint32_t, uint32_t>* map;'
+    print '} SCRIPT_PARENTS[] = {'
+    for script in sorted_scripts:
+        print "    {{'%c', '%c', '%c', '%c'}, &%s_PARENTS}," % (
+            script[0], script[1], script[2], script[3],
+            script.upper())
+    print '};'
+
+
+def dump_parent_tree_depth(parent_dict):
+    """Find and dump the depth of the parent tree."""
+    max_depth = 1
+    for locale, _ in parent_dict.items():
+        depth = 1
+        while locale in parent_dict:
+            locale = parent_dict[locale]
+            depth += 1
+        max_depth = max(max_depth, depth)
+    assert max_depth < 5 # Our algorithms assume small max_depth
+    print
+    print 'const size_t MAX_PARENT_DEPTH = %d;' % max_depth
+
+
+def read_and_dump_parent_data(icu_data_dir, likely_script_dict):
+    """Read parent data from ICU and dump it."""
+    parent_dict = read_parent_data(icu_data_dir)
+    script_organized_dict = collections.defaultdict(dict)
+    for locale in parent_dict:
+        parent = parent_dict[locale]
+        if parent == 'root':
+            continue
+        script = get_likely_script(locale, likely_script_dict)
+        script_organized_dict[script][locale] = parent_dict[locale]
+    dump_parent_data(script_organized_dict)
+    dump_parent_tree_depth(parent_dict)
+
+
+def main():
+    """Read the data files from ICU and dump the output to a C++ file."""
+    source_root = sys.argv[1]
+    icu_data_dir = os.path.join(
+        source_root,
+        'external', 'icu', 'icu4c', 'source', 'data')
+
+    print '// Auto-generated by %s' % sys.argv[0]
+    print
+    likely_script_dict = read_and_dump_likely_data(icu_data_dir)
+    read_and_dump_parent_data(icu_data_dir, likely_script_dict)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 0c06ae8..274e985 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -78,6 +78,7 @@
           * (requires {@code preSharedKey} to be specified).
           * @hide
           */
+        @SystemApi
         public static final int WPA2_PSK = 4;
 
         public static final String varName = "key_mgmt";
@@ -760,7 +761,8 @@
          * selection status value as index to extec the corresponding debug string
          */
         private static final String[] QUALITY_NETWORK_SELECTION_STATUS = {
-                "NETWORK_SELECTION_ENABLED", "NETWORK_SELECTION_TEMPORARY_DISABLED",
+                "NETWORK_SELECTION_ENABLED",
+                "NETWORK_SELECTION_TEMPORARY_DISABLED",
                 "NETWORK_SELECTION_PERMANENTLY_DISABLED"};
 
         //Quality Network disabled reasons
@@ -813,12 +815,15 @@
          * Quality network selection disable reason String (for debug purpose)
          */
         private static final String[] QUALITY_NETWORK_SELECTION_DISABLE_REASON = {
-                "NETWORK_SELECTION_ENABLE", "NETWORK_SELECTION_DISABLED_BAD_LINK",
+                "NETWORK_SELECTION_ENABLE",
+                "NETWORK_SELECTION_DISABLED_BAD_LINK",
                 "NETWORK_SELECTION_DISABLED_ASSOCIATION_REJECTION ",
                 "NETWORK_SELECTION_DISABLED_AUTHENTICATION_FAILURE",
                 "NETWORK_SELECTION_DISABLED_DHCP_FAILURE",
-                "NETWORK_SELECTION_DISABLED_DNS_FAILURE", "NETWORK_SELECTION_DISABLED_TLS_VERSION",
+                "NETWORK_SELECTION_DISABLED_DNS_FAILURE",
+                "NETWORK_SELECTION_DISABLED_TLS_VERSION",
                 "NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_CREDENTIALS",
+                "NETWORK_SELECTION_DISABLED_NO_INTERNET",
                 "NETWORK_SELECTION_DISABLED_BY_WIFI_MANAGER"};
 
         /**
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index c1269f9..db40cd8 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1435,8 +1435,9 @@
      *        part of WifiConfiguration
      * @return {@code true} if the operation succeeds, {@code false} otherwise
      *
-     * @hide Dont open up yet
+     * @hide
      */
+    @SystemApi
     public boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
         try {
             mService.setWifiApEnabled(wifiConfig, enabled);
@@ -1453,8 +1454,9 @@
      *         {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED}
      * @see #isWifiApEnabled()
      *
-     * @hide Dont open yet
+     * @hide
      */
+    @SystemApi
     public int getWifiApState() {
         try {
             return mService.getWifiApEnabledState();
@@ -1468,8 +1470,9 @@
      * @return {@code true} if Wi-Fi AP is enabled
      * @see #getWifiApState()
      *
-     * @hide Dont open yet
+     * @hide
      */
+    @SystemApi
     public boolean isWifiApEnabled() {
         return getWifiApState() == WIFI_AP_STATE_ENABLED;
     }
@@ -1478,8 +1481,9 @@
      * Gets the Wi-Fi AP Configuration.
      * @return AP details in WifiConfiguration
      *
-     * @hide Dont open yet
+     * @hide
      */
+    @SystemApi
     public WifiConfiguration getWifiApConfiguration() {
         try {
             return mService.getWifiApConfiguration();
@@ -1507,8 +1511,9 @@
      * Sets the Wi-Fi AP Configuration.
      * @return {@code true} if the operation succeeded, {@code false} otherwise
      *
-     * @hide Dont open yet
+     * @hide
      */
+    @SystemApi
     public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) {
         try {
             mService.setWifiApConfiguration(wifiConfig);